标签:网络流
1 5 6 2 2 1 2 2 1 3 1 1 1 2 3 1 1 2 1 2
3 0 2 1HintNo city was rebuilt in the third year,city 1 and city 3 were rebuilt in the fourth year,and city 2 was rebuilt in the sixth year. 题意: 一个国家原本有n个城市和若干条联通城市的路,可是在M年前,因为一场大地震,整个国家都被摧毁了. 现在打算在m年里,重建国家,有三个操作: 1.> 输入1,x,表示可以修建包含x在内的间接或者直接相连的城市. 2.> 输入2,x,y表示新建x到y的无向边 3.> 输入3,p,表示要摧毁p条道路,接下来输入2p个数,分别表示p条路; 最后问最终能够修建多少个城市.和输出一个字典序最小的方案; 题解: 网络流可以做; 把年份分为一边,城市分为另一边,连边构图; 从s往所有年份连一条容量为k的边,所有城市往汇点t连一条容量为1的边; 其他的点,按照关系连一条容量为1的边; 因为题目要求以最小字典序输出,所以我们从后往前做网络流; AC代码:/* *********************************************** Author :xdlove Created Time :2015年07月31日 星期五 12时37分29秒 File Name :a.cpp ************************************************ */ #pragma comment(linker, "/STACK:1024000000,1024000000") #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; /**宏定义类 * **/ #define FOR(i,s,t) for(int i = (s); i < (t); i++) #define FOR_REV(i,s,t) for(int i = (s - 1); i >= (t); i--) #define mid ((l + r) >> 1) #define clr(a) memset(a,0,sizeof(a)) #define lson l,mid,u<<1 #define rson mid+1,r,u<<1|1 #define ls u<<1 #define rs u<<1|1 typedef long long ll; typedef unsigned long long ull; const int INF = 0x3f3f3f3f; const double pi = acos(-1.0); /**输入输出挂类模板 * **/ class Fast { public: inline void rd(int &ret) { char c; int sgn; if(c = getchar(),c == EOF) return; while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(),c >= '0' && c <= '9') ret = ret * 10 + c - '0'; ret *= sgn; } public: inline void pt(int x) { if(x < 0) { putchar('-'); x = -x; } if(x > 9) pt(x / 10); putchar(x % 10 + '0'); } }; Fast xd; const int MAXM = 1e6; const int MAXN = 1000; struct Node { int from,to,next; int cap; }edge[MAXM * 2]; int tol; int Head[MAXN]; int que[MAXN]; int dep[MAXN]; //dep为点的层次 int stack[MAXN];//stack为栈,存储当前增广路 int cur[MAXN],cnt;//存储当前点的后继 void Init() { tol = cnt = 0; memset(Head,-1,sizeof(Head)); } void add_edge(int u, int v, int w) { //printf("%d: %d: %d\n",u,v,w); edge[tol].from = u; edge[tol].to = v; edge[tol].cap = w; edge[tol].next = Head[u]; Head[u] = tol++; edge[tol].from = v; edge[tol].to = u; edge[tol].cap = 0; edge[tol].next = Head[v]; Head[v] = tol++; } int BFS(int start, int end) { int front, rear; front = rear = 0; memset(dep, -1, sizeof(dep)); que[rear++] = start; dep[start] = 0; while (front != rear) { int u = que[front++]; if (front == MAXN)front = 0; for (int i = Head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && dep[v] == -1) { dep[v] = dep[u] + 1; que[rear++] = v; if (rear >= MAXN)rear = 0; if (v == end)return 1; } } } return 0; } int dinic(int start, int end) { int res = 0; int top; while (BFS(start, end)) { memcpy(cur, Head, sizeof(Head)); int u = start; top = 0; while (true) { if (u == end) { int min = INF; int loc; for (int i = 0; i < top; i++) if (min > edge[stack[i]].cap) { min = edge[stack[i]].cap; loc = i; } for (int i = 0; i < top; i++) { edge[stack[i]].cap -= min; edge[stack[i] ^ 1].cap += min; } res += min; top = loc; u = edge[stack[top]].from; } for (int i = cur[u]; i != -1; cur[u] = i = edge[i].next) if (edge[i].cap != 0 && dep[u] + 1 == dep[edge[i].to]) break; if (cur[u] != -1) { stack[top++] = cur[u]; u = edge[cur[u]].to; } else { if (top == 0)break; dep[u] = -1; u = edge[stack[--top]].from; } } } return res; } int g[205][205],used[205]; int Stack[600]; int n,m,k; void dfs(int u) { used[u] = 1; add_edge(cnt,u + m,1); FOR(v, 1, 1 + n) { if(g[u][v] && !used[v]) { used[v] = 1; dfs(v); } } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; xd.rd(T); while(T--) { Init(); xd.rd(n); xd.rd(m); xd.rd(k); clr(g); clr(used); vector<int> p; FOR(i, 0, m) { int o,x,y; xd.rd(o); if(o == 2) { xd.rd(x); xd.rd(y); g[x][y] = g[y][x] = 1; } else if(o == 3) { xd.rd(o); FOR(i, 0, o) { xd.rd(x); xd.rd(y); g[x][y] = g[y][x] = 0; } } else { cnt++; clr(used); p.push_back(cnt); xd.rd(x); dfs(x); } } int s = 0,t = n + m + 1; for(int i = 1; i <= n; i++) add_edge(i + m,t,1); int pos = 0,sum = 0; for(vector<int> :: iterator it = --p.end(); ; it--) { int id = *it; //cout<<id<<endl; add_edge(s,id,k); Stack[pos++] = dinic(s,t); sum += Stack[pos - 1]; if(it == p.begin()) break; } printf("%d\n",sum); FOR_REV(i,pos,0) { if(i != pos - 1) putchar(' '); printf("%d",Stack[i]); } puts(""); } return 0; }
版权声明:追逐心中的梦想,永不放弃! By-xdlove
标签:网络流
原文地址:http://blog.csdn.net/zsgg_acm/article/details/47301977