Dinic模板
1 int n, m, T; 2 int st, en; 3 4 const int INF=0x3f3f3f3f; 5 const int MAXN = 1122;//点数的最大值 6 const int MAXM = 355555;//边数的最大值 7 8 struct Node 9 { 10 int from,to,next; 11 int cap; 12 }edge[MAXM]; 13 int tol; 14 15 int dep[MAXN];//dep为点的层次 16 int head[MAXN]; 17 18 void init() 19 { 20 tol=0; 21 memset(head,-1,sizeof(head)); 22 } 23 void addedge(int u,int v,int w)//第一条变下标必须为偶数 24 { 25 edge[tol].from=u; 26 edge[tol].to=v; 27 edge[tol].cap=w; 28 edge[tol].next=head[u]; 29 head[u]=tol++; 30 edge[tol].from=v; 31 edge[tol].to=u; 32 edge[tol].cap=0; 33 edge[tol].next=head[v]; 34 head[v]=tol++; 35 } 36 37 int BFS(int start,int end) 38 { 39 int que[MAXN]; 40 int front,rear; 41 front=rear=0; 42 memset(dep,-1,sizeof(dep)); 43 que[rear++]=start; 44 dep[start]=0; 45 while(front!=rear) 46 { 47 int u=que[front++]; 48 if(front==MAXN)front=0; 49 for(int i=head[u];i!=-1;i=edge[i].next) 50 { 51 int v=edge[i].to; 52 if(edge[i].cap>0&&dep[v]==-1) 53 { 54 dep[v]=dep[u]+1; 55 que[rear++]=v; 56 if(rear>=MAXN)rear=0; 57 if(v==end)return 1; 58 } 59 } 60 } 61 return 0; 62 } 63 int dinic(int start,int end) 64 { 65 int res=0; 66 int top; 67 int stack[MAXN];//stack为栈,存储当前增广路 68 int cur[MAXN];//存储当前点的后继 69 while(BFS(start,end)) 70 { 71 memcpy(cur,head,sizeof(head)); 72 int u=start; 73 top=0; 74 while(1) 75 { 76 if(u==end) 77 { 78 int min=INF; 79 int loc; 80 for(int i=0;i<top;i++) 81 if(min>edge[stack[i]].cap) 82 { 83 min=edge[stack[i]].cap; 84 loc=i; 85 } 86 for(int i=0;i<top;i++) 87 { 88 edge[stack[i]].cap-=min; 89 edge[stack[i]^1].cap+=min; 90 } 91 res+=min; 92 top=loc; 93 u=edge[stack[top]].from; 94 } 95 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 96 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 97 break; 98 if(cur[u]!=-1) 99 { 100 stack[top++]=cur[u]; 101 u=edge[cur[u]].to; 102 } 103 else 104 { 105 if(top==0)break; 106 dep[u]=-1; 107 u=edge[stack[--top]].from; 108 } 109 } 110 } 111 return res; 112 }
最小费用最大流
1 /*Author :usedrose */ 2 /*Created Time :2015/7/26 22:29:35*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define OK cout << "ok" << endl; 24 #define o(a) cout << #a << " = " << a << endl 25 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 26 using namespace std; 27 typedef long long LL; 28 29 //最小费用最大流,求最大费用只需要取相反数,结果取相反数即可。 30 //点的总数为 N,点的编号 0~N-1 31 const int MAXN = 10000; 32 const int MAXM = 100000; 33 34 int n,m; 35 36 int A[MAXN],B[MAXN],X[MAXN],Y[MAXN]; 37 38 struct Edge 39 { 40 int to,next,cap,flow,cost; 41 }edge[MAXM]; 42 int head[MAXN],tol; 43 int pre[MAXN],dis[MAXN]; 44 bool vis[MAXN]; 45 int N;//节点总个数,节点编号从0~N-1 46 47 void init(int n) 48 { 49 N = n; 50 tol = 0; 51 memset(head,-1,sizeof(head)); 52 } 53 54 void addedge(int u,int v,int cap,int cost) 55 { 56 edge[tol].to = v; 57 edge[tol].cap = cap; 58 edge[tol].cost = cost; 59 edge[tol].flow = 0; 60 edge[tol].next = head[u]; 61 head[u] = tol++; 62 edge[tol].to = u; 63 edge[tol].cap = 0; 64 edge[tol].cost = -cost; 65 edge[tol].flow = 0; 66 edge[tol].next = head[v]; 67 head[v] = tol++; 68 } 69 70 bool spfa(int s,int t) 71 { 72 queue<int>q; 73 for(int i = 0;i < N;i++) 74 { 75 dis[i] = INF; 76 vis[i] = false; 77 pre[i] = -1; 78 } 79 dis[s] = 0; 80 vis[s] = true; 81 q.push(s); 82 while(!q.empty()) 83 { 84 int u = q.front(); 85 q.pop(); 86 vis[u] = false; 87 for(int i = head[u]; i != -1;i = edge[i].next) 88 { 89 int v = edge[i].to; 90 if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) 91 { 92 dis[v] = dis[u] + edge[i].cost; 93 pre[v] = i; 94 if(!vis[v]) 95 { 96 vis[v] = true; 97 q.push(v); 98 } 99 } 100 } 101 } 102 if(pre[t] == -1) return false; 103 else return true; 104 } 105 106 //返回的是最大流, cost存的是最小费用 107 int minCostMaxflow(int s,int t,int &cost) 108 { 109 int flow = 0; 110 cost = 0; 111 while(spfa(s,t)) 112 { 113 int Min = INF; 114 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 115 { 116 if(Min > edge[i].cap - edge[i].flow) 117 Min = edge[i].cap - edge[i].flow; 118 } 119 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 120 { 121 edge[i].flow += Min; 122 edge[i^1].flow -= Min; 123 cost += edge[i].cost * Min; 124 } 125 flow += Min; 126 } 127 return flow; 128 } 129 130 131 int main() 132 { 133 //freopen("data.in","r",stdin); 134 //freopen("data.out","w",stdout); 135 cin.tie(0); 136 ios::sync_with_stdio(false); 137 while (cin >> n >> m) { 138 int all = 0; 139 init(n+2); 140 int s = 0, t = n+1; 141 for (int i = 1;i <= n; ++ i) { 142 cin >> A[i] >> B[i]; 143 if (A[i] > B[i]) 144 addedge(s, i, A[i]-B[i], 0); 145 else if (A[i] < B[i]) { 146 addedge(i, t, B[i]-A[i], 0); 147 all += (B[i] - A[i]); 148 } 149 } 150 int u, v; 151 for (int i = 0;i < m; ++ i) { 152 cin >> u >> v; 153 addedge(u, v, INF, 1); 154 addedge(v, u, INF, 1); 155 } 156 int cost, ans; 157 ans = minCostMaxflow(s, t, cost); 158 if (ans < all) cout << -1 << endl; 159 else cout << cost << endl; 160 } 161 return 0; 162 }
【HDU】
1532 Drainage Ditches(入门) [最大流]
3549 Flow Problem(入门) [最大流]
3572 Task Schedule(基础) [最大流]任务分配,判断满流
1 /*Author :usedrose */ 2 /*Created Time :2015/8/27 15:47:27*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define eps 1e-8 22 #define OK cout << "ok" << endl; 23 #define o(a) cout << #a << " = " << a << endl 24 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 25 using namespace std; 26 typedef long long LL; 27 28 int n, m, T; 29 int st, en; 30 31 const int INF=0x3f3f3f3f; 32 const int MAXN = 1122;//点数的最大值 33 const int MAXM = 355555;//边数的最大值 34 35 struct Node 36 { 37 int from,to,next; 38 int cap; 39 }edge[MAXM]; 40 int tol; 41 42 int dep[MAXN];//dep为点的层次 43 int head[MAXN]; 44 45 void init() 46 { 47 tol=0; 48 memset(head,-1,sizeof(head)); 49 } 50 void addedge(int u,int v,int w)//第一条变下标必须为偶数 51 { 52 edge[tol].from=u; 53 edge[tol].to=v; 54 edge[tol].cap=w; 55 edge[tol].next=head[u]; 56 head[u]=tol++; 57 edge[tol].from=v; 58 edge[tol].to=u; 59 edge[tol].cap=0; 60 edge[tol].next=head[v]; 61 head[v]=tol++; 62 } 63 64 int BFS(int start,int end) 65 { 66 int que[MAXN]; 67 int front,rear; 68 front=rear=0; 69 memset(dep,-1,sizeof(dep)); 70 que[rear++]=start; 71 dep[start]=0; 72 while(front!=rear) 73 { 74 int u=que[front++]; 75 if(front==MAXN)front=0; 76 for(int i=head[u];i!=-1;i=edge[i].next) 77 { 78 int v=edge[i].to; 79 if(edge[i].cap>0&&dep[v]==-1) 80 { 81 dep[v]=dep[u]+1; 82 que[rear++]=v; 83 if(rear>=MAXN)rear=0; 84 if(v==end)return 1; 85 } 86 } 87 } 88 return 0; 89 } 90 int dinic(int start,int end) 91 { 92 int res=0; 93 int top; 94 int stack[MAXN];//stack为栈,存储当前增广路 95 int cur[MAXN];//存储当前点的后继 96 while(BFS(start,end)) 97 { 98 memcpy(cur,head,sizeof(head)); 99 int u=start; 100 top=0; 101 while(1) 102 { 103 if(u==end) 104 { 105 int min=INF; 106 int loc; 107 for(int i=0;i<top;i++) 108 if(min>edge[stack[i]].cap) 109 { 110 min=edge[stack[i]].cap; 111 loc=i; 112 } 113 for(int i=0;i<top;i++) 114 { 115 edge[stack[i]].cap-=min; 116 edge[stack[i]^1].cap+=min; 117 } 118 res+=min; 119 top=loc; 120 u=edge[stack[top]].from; 121 } 122 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 123 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 124 break; 125 if(cur[u]!=-1) 126 { 127 stack[top++]=cur[u]; 128 u=edge[cur[u]].to; 129 } 130 else 131 { 132 if(top==0)break; 133 dep[u]=-1; 134 u=edge[stack[--top]].from; 135 } 136 } 137 } 138 return res; 139 } 140 141 142 int main() 143 { 144 scanf("%d", &T); 145 int ncase = 1; 146 while (T--) { 147 scanf("%d%d", &n, &m); 148 init(); 149 int pi, si, ei; 150 int sum = 0; 151 for (int i = 1;i <= n; ++ i) { 152 scanf("%d%d%d", &pi, &si, &ei); 153 sum += pi; 154 addedge(0, i, pi); 155 for (int j = si;j <= ei; ++ j) 156 addedge(i, j+n, 1); 157 } 158 st = 0, en = 500 + 2 + n; 159 for (int i = n+1;i <= 500 + n; ++ i) 160 addedge(i, en, m); 161 printf("Case %d: ", ncase++); 162 if (sum == dinic(st, en)) puts("Yes"); 163 else puts("No"); 164 puts(""); 165 } 166 return 0; 167 }
2732 Leapin' Lizards(较难) [最大流]
1 /*Author :usedrose */ 2 /*Created Time :2015/8/27 15:47:27*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define eps 1e-8 22 #define OK cout << "ok" << endl; 23 #define o(a) cout << #a << " = " << a << endl 24 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 25 using namespace std; 26 typedef long long LL; 27 28 int n, m, T, d; 29 int st, en; 30 31 const int INF=0x3f3f3f3f; 32 const int MAXN = 1122;//点数的最大值 33 const int MAXM = 35555;//边数的最大值 34 35 struct Node 36 { 37 int from,to,next; 38 int cap; 39 }edge[MAXM]; 40 int tol; 41 42 int dep[MAXN];//dep为点的层次 43 int head[MAXN]; 44 45 void init() 46 { 47 tol=0; 48 memset(head,-1,sizeof(head)); 49 } 50 void addedge(int u,int v,int w)//第一条变下标必须为偶数 51 { 52 edge[tol].from=u; 53 edge[tol].to=v; 54 edge[tol].cap=w; 55 edge[tol].next=head[u]; 56 head[u]=tol++; 57 edge[tol].from=v; 58 edge[tol].to=u; 59 edge[tol].cap=0; 60 edge[tol].next=head[v]; 61 head[v]=tol++; 62 } 63 64 int BFS(int start,int end) 65 { 66 int que[MAXN]; 67 int front,rear; 68 front=rear=0; 69 memset(dep,-1,sizeof(dep)); 70 que[rear++]=start; 71 dep[start]=0; 72 while(front!=rear) 73 { 74 int u=que[front++]; 75 if(front==MAXN)front=0; 76 for(int i=head[u];i!=-1;i=edge[i].next) 77 { 78 int v=edge[i].to; 79 if(edge[i].cap>0&&dep[v]==-1) 80 { 81 dep[v]=dep[u]+1; 82 que[rear++]=v; 83 if(rear>=MAXN)rear=0; 84 if(v==end)return 1; 85 } 86 } 87 } 88 return 0; 89 } 90 int dinic(int start,int end) 91 { 92 int res=0; 93 int top; 94 int stack[MAXN];//stack为栈,存储当前增广路 95 int cur[MAXN];//存储当前点的后继 96 while(BFS(start,end)) 97 { 98 memcpy(cur,head,sizeof(head)); 99 int u=start; 100 top=0; 101 while(1) 102 { 103 if(u==end) 104 { 105 int min=INF; 106 int loc; 107 for(int i=0;i<top;i++) 108 if(min>edge[stack[i]].cap) 109 { 110 min=edge[stack[i]].cap; 111 loc=i; 112 } 113 for(int i=0;i<top;i++) 114 { 115 edge[stack[i]].cap-=min; 116 edge[stack[i]^1].cap+=min; 117 } 118 res+=min; 119 top=loc; 120 u=edge[stack[top]].from; 121 } 122 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 123 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 124 break; 125 if(cur[u]!=-1) 126 { 127 stack[top++]=cur[u]; 128 u=edge[cur[u]].to; 129 } 130 else 131 { 132 if(top==0)break; 133 dep[u]=-1; 134 u=edge[stack[--top]].from; 135 } 136 } 137 } 138 return res; 139 } 140 141 142 int main() 143 { 144 scanf("%d", &T); 145 string s; 146 for (int ncase = 1;ncase <= T ;++ ncase) { 147 cin >> n >> d; 148 init(); 149 for (int i = 1;i <= n; ++ i) { 150 cin >> s; 151 if (i == 1) { 152 m = s.length(); 153 st = 0, en = 2*n*m + 1; 154 } 155 for (int j = 0;j < m; ++ j) { 156 int k = s[j] - '0'; 157 if (k == 0) continue; 158 int cur = i*m + j + 1 - m; 159 addedge(cur, cur+n*m, k); 160 if (i <= d || n-i < d || j < d || m-j <= d) addedge(cur+n*m, en, INF); 161 else { 162 for (int k = 1;k <= n; ++ k) 163 for (int l = 0;l < m; ++ l) { 164 int now = k*m + l + 1 - m; 165 if (now == cur) continue; 166 if (abs(i-k) + abs(j-l) <= d) addedge(cur+n*m, now, INF); 167 } 168 } 169 } 170 } 171 int sum = 0; 172 for (int i = 0;i < n; ++ i) { 173 cin >> s; 174 for (int j = 0;j < m; ++ j) { 175 int cur = i*m+j+1; 176 if (s[j] == 'L') { 177 sum++; 178 addedge(st, cur, 1); 179 } 180 } 181 } 182 int ans = sum - dinic(st, en); 183 if(ans == 0) printf("Case #%d: no lizard was left behind. ", ncase); 184 else if(ans == 1) printf("Case #%d: 1 lizard was left behind. ", ncase); 185 else printf("Case #%d: %d lizards were left behind. ", ncase, ans); 186 } 187 return 0; 188 }
3338 Kakuro Extension(较难,好题) [最大流][数和]神奇最大流行进列出
2883 kebab(中等) [最大流]判断满流
3605 Escape(中等,好题) [最大流](可用多重匹配)
1 /*Author :usedrose */ 2 /*Created Time :2015/8/27 1:45:04*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define MAXN 1110 25 #define MAXM 11 26 #define OK cout << "ok" << endl; 27 #define o(a) cout << #a << " = " << a << endl 28 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 29 using namespace std; 30 typedef long long LL; 31 32 int n, m, msk; 33 int c[MAXM], cnt[1033]; 34 35 36 int main() 37 { 38 //freopen("data.in","r",stdin); 39 //freopen("data.out","w",stdout); 40 cin.tie(0); 41 ios::sync_with_stdio(false); 42 while (cin >> n >> m) { 43 init(); 44 int x; 45 for (int i = 0;i < n; ++ i) { 46 msk = 0; 47 for (int j = 0;j < m; ++ j) { 48 cin >> x; 49 if (x) msk |= (1<<j); 50 } 51 cnt[msk]++; 52 } 53 int nn = n; 54 n = 1<<m; 55 for (int i = 0;i <= (1<<m); ++ i) 56 if (cnt[i]) { 57 addedge(0, i, cnt[i]); 58 for (int j = 0;j < 11; ++ j) { 59 if ((1<<j)&i) 60 addedge(i, n+j, INF); 61 } 62 } 63 for (int i = 0;i < m; ++ i) { 64 cin >> x; 65 if (x) addedge(n+i, n+m, x); 66 } 67 //st = 0, en = n+m, point_num = n+m+1; 68 if (nn == max_flow(0, n+m, n+m+1)) cout << "YES" << endl; 69 else cout << "NO" << endl; 70 71 } 72 return 0; 73 }
4183 Pahom on Water(基础) [最大流]来回走不重复点的网络流.
1 /*Author :usedrose */ 2 /*Created Time :2015/8/28 14:27:41*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 322;//点数的最大值 30 const int MAXM = 100555;//边数的最大值 31 32 33 int T, n; 34 struct node{ 35 double f; 36 int x, y, r; 37 bool operator<(node const ss) const { 38 return f < ss.f; 39 } 40 }p[MAXN]; 41 int st, en; 42 struct Node 43 { 44 int from,to,next; 45 int cap; 46 }edge[MAXM]; 47 int tol; 48 49 int dep[MAXN];//dep为点的层次 50 int head[MAXN]; 51 52 void init() 53 { 54 tol=0; 55 memset(head,-1,sizeof(head)); 56 } 57 void addedge(int u,int v,int w)//第一条变下标必须为偶数 58 { 59 edge[tol].from=u; 60 edge[tol].to=v; 61 edge[tol].cap=w; 62 edge[tol].next=head[u]; 63 head[u]=tol++; 64 edge[tol].from=v; 65 edge[tol].to=u; 66 edge[tol].cap=0; 67 edge[tol].next=head[v]; 68 head[v]=tol++; 69 } 70 71 int BFS(int start,int end) 72 { 73 int que[MAXN]; 74 int front,rear; 75 front=rear=0; 76 memset(dep,-1,sizeof(dep)); 77 que[rear++]=start; 78 dep[start]=0; 79 while(front!=rear) 80 { 81 int u=que[front++]; 82 if(front==MAXN)front=0; 83 for(int i=head[u];i!=-1;i=edge[i].next) 84 { 85 int v=edge[i].to; 86 if(edge[i].cap>0&&dep[v]==-1) 87 { 88 dep[v]=dep[u]+1; 89 que[rear++]=v; 90 if(rear>=MAXN)rear=0; 91 if(v==end)return 1; 92 } 93 } 94 } 95 return 0; 96 } 97 int dinic(int start,int end) 98 { 99 int res=0; 100 int top; 101 int stack[MAXN];//stack为栈,存储当前增广路 102 int cur[MAXN];//存储当前点的后继 103 while(BFS(start,end)) 104 { 105 memcpy(cur,head,sizeof(head)); 106 int u=start; 107 top=0; 108 while(1) 109 { 110 if(u==end) 111 { 112 int min=INF; 113 int loc; 114 for(int i=0;i<top;i++) 115 if(min>edge[stack[i]].cap) 116 { 117 min=edge[stack[i]].cap; 118 loc=i; 119 } 120 for(int i=0;i<top;i++) 121 { 122 edge[stack[i]].cap-=min; 123 edge[stack[i]^1].cap+=min; 124 } 125 res+=min; 126 top=loc; 127 u=edge[stack[top]].from; 128 } 129 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 130 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 131 break; 132 if(cur[u]!=-1) 133 { 134 stack[top++]=cur[u]; 135 u=edge[cur[u]].to; 136 } 137 else 138 { 139 if(top==0)break; 140 dep[u]=-1; 141 u=edge[stack[--top]].from; 142 } 143 } 144 } 145 return res; 146 } 147 148 bool cmp(double a, double b) 149 { 150 if (fabs(a-b) < 1e-4) return true; 151 return false; 152 } 153 154 double dis(node a, node b) 155 { 156 return sqrt(0.0 + (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); 157 } 158 159 bool isIntersect(node a, node b) 160 { 161 if (a.r + b.r + 0.0 > dis(a, b)+0.0) return true; 162 return false; 163 } 164 165 int main() 166 { 167 //freopen("data.in","r",stdin); 168 //freopen("data.out","w",stdout); 169 cin.tie(0); 170 ios::sync_with_stdio(false); 171 cin >> T; 172 while (T--) { 173 cin >> n; 174 init(); 175 for (int i = 0;i < n; ++ i) { 176 cin >> p[i].f >> p[i].x >> p[i].y >> p[i].r; 177 } 178 sort(p, p+n); 179 if (isIntersect(p[0], p[n-1])) { 180 cout << "Game is VALID" << endl; 181 continue; 182 } 183 for (int i = 0;i < n; ++ i) 184 for (int j = i+1;j < n; ++ j) { 185 if (isIntersect(p[i], p[j]) && p[i].f < p[j].f) 186 addedge(i, j, 1); 187 } 188 st = 0, en = n-1; 189 if (dinic(st, en) >= 2) cout << "Game is VALID" << endl; 190 else cout << "Game is NOT VALID" << endl; 191 } 192 return 0; 193 }
4240 Route Redundancy(基础) [最大流]一条流最大的路径
1 /*Author :usedrose */ 2 /*Created Time :2015/8/28 14:27:41*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 1022;//点数的最大值 30 const int MAXM = 400555;//边数的最大值 31 32 int T, n, m; 33 int st, en; 34 struct Node 35 { 36 int from,to,next; 37 int cap; 38 }edge[MAXM]; 39 int tol; 40 41 int dep[MAXN];//dep为点的层次 42 int head[MAXN]; 43 bool vis[MAXN]; 44 int minMaxflow; 45 46 void init() 47 { 48 minMaxflow = 0; 49 tol=0; 50 memset(head,-1,sizeof(head)); 51 memset(vis, 0, sizeof(vis)); 52 } 53 void addedge(int u,int v,int w)//第一条变下标必须为偶数 54 { 55 edge[tol].from=u; 56 edge[tol].to=v; 57 edge[tol].cap=w; 58 edge[tol].next=head[u]; 59 head[u]=tol++; 60 edge[tol].from=v; 61 edge[tol].to=u; 62 edge[tol].cap=0; 63 edge[tol].next=head[v]; 64 head[v]=tol++; 65 } 66 67 int BFS(int start,int end) 68 { 69 int que[MAXN]; 70 int front,rear; 71 front=rear=0; 72 memset(dep,-1,sizeof(dep)); 73 que[rear++]=start; 74 dep[start]=0; 75 while(front!=rear) 76 { 77 int u=que[front++]; 78 if(front==MAXN)front=0; 79 for(int i=head[u];i!=-1;i=edge[i].next) 80 { 81 int v=edge[i].to; 82 if(edge[i].cap>0&&dep[v]==-1) 83 { 84 dep[v]=dep[u]+1; 85 que[rear++]=v; 86 if(rear>=MAXN)rear=0; 87 if(v==end)return 1; 88 } 89 } 90 } 91 return 0; 92 } 93 int dinic(int start,int end) 94 { 95 int res=0; 96 int top; 97 int stack[MAXN];//stack为栈,存储当前增广路 98 int cur[MAXN];//存储当前点的后继 99 while(BFS(start,end)) 100 { 101 memcpy(cur,head,sizeof(head)); 102 int u=start; 103 top=0; 104 while(1) 105 { 106 if(u==end) 107 { 108 int min=INF; 109 int loc; 110 for(int i=0;i<top;i++) 111 if(min>edge[stack[i]].cap) 112 { 113 min=edge[stack[i]].cap; 114 loc=i; 115 } 116 for(int i=0;i<top;i++) 117 { 118 edge[stack[i]].cap-=min; 119 edge[stack[i]^1].cap+=min; 120 } 121 res+=min; 122 top=loc; 123 u=edge[stack[top]].from; 124 } 125 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 126 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 127 break; 128 if(cur[u]!=-1) 129 { 130 stack[top++]=cur[u]; 131 u=edge[cur[u]].to; 132 } 133 else 134 { 135 if(top==0)break; 136 dep[u]=-1; 137 u=edge[stack[--top]].from; 138 } 139 } 140 } 141 return res; 142 } 143 144 int dfs(int u, int now) 145 { 146 int cur = 0; 147 if (u == en) return now; 148 for (int i = head[u]; i != -1; i = edge[i].next) { 149 int v = edge[i].to; 150 if (vis[v]) continue; 151 vis[v] = 1; 152 cur = max(dfs(v, min(now, edge[i].cap)), cur); 153 vis[v] = 0; 154 } 155 return cur; 156 } 157 158 int main() 159 { 160 scanf("%d", &T); 161 int t, x ,y , c; 162 for (int ss = 1;ss <= T; ++ ss) { 163 scanf("%d%d%d%d%d", &t, &n, &m, &st, &en); 164 init(); 165 for (int i = 0;i < m; ++ i) { 166 scanf("%d%d%d", &x, &y, &c); 167 addedge(x, y, c); 168 } 169 int aa = dfs(st, INF); 170 int k = dinic(st, en); 171 double ans = k*1.0/aa; 172 printf("%d %.3lf ", ss, ans); 173 } 174 return 0; 175 }
3081 Marriage Match II(中等,好题) [二分最大流]+并查集
1 /*Author :usedrose */ 2 /*Created Time :2015/8/28 14:27:41*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 222;//点数的最大值 30 const int MAXM = 50555;//边数的最大值 31 32 int T, n, m, k; 33 int st, en; 34 struct Node 35 { 36 int from,to,next; 37 int cap; 38 }edge[MAXM]; 39 int tol; 40 41 int dep[MAXN];//dep为点的层次 42 int head[MAXN]; 43 bool match[MAXN][MAXN]; 44 int fa[MAXN]; 45 46 void init() 47 { 48 tol=0; 49 memset(head,-1,sizeof(head)); 50 memset(match, 0, sizeof(match)); 51 } 52 void addedge(int u,int v,int w)//第一条变下标必须为偶数 53 { 54 edge[tol].from=u; 55 edge[tol].to=v; 56 edge[tol].cap=w; 57 edge[tol].next=head[u]; 58 head[u]=tol++; 59 edge[tol].from=v; 60 edge[tol].to=u; 61 edge[tol].cap=0; 62 edge[tol].next=head[v]; 63 head[v]=tol++; 64 } 65 66 int BFS(int start,int end) 67 { 68 int que[MAXN]; 69 int front,rear; 70 front=rear=0; 71 memset(dep,-1,sizeof(dep)); 72 que[rear++]=start; 73 dep[start]=0; 74 while(front!=rear) 75 { 76 int u=que[front++]; 77 if(front==MAXN)front=0; 78 for(int i=head[u];i!=-1;i=edge[i].next) 79 { 80 int v=edge[i].to; 81 if(edge[i].cap>0&&dep[v]==-1) 82 { 83 dep[v]=dep[u]+1; 84 que[rear++]=v; 85 if(rear>=MAXN)rear=0; 86 if(v==end)return 1; 87 } 88 } 89 } 90 return 0; 91 } 92 int dinic(int start,int end) 93 { 94 int res=0; 95 int top; 96 int stack[MAXN];//stack为栈,存储当前增广路 97 int cur[MAXN];//存储当前点的后继 98 while(BFS(start,end)) 99 { 100 memcpy(cur,head,sizeof(head)); 101 int u=start; 102 top=0; 103 while(1) 104 { 105 if(u==end) 106 { 107 int min=INF; 108 int loc; 109 for(int i=0;i<top;i++) 110 if(min>edge[stack[i]].cap) 111 { 112 min=edge[stack[i]].cap; 113 loc=i; 114 } 115 for(int i=0;i<top;i++) 116 { 117 edge[stack[i]].cap-=min; 118 edge[stack[i]^1].cap+=min; 119 } 120 res+=min; 121 top=loc; 122 u=edge[stack[top]].from; 123 } 124 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 125 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 126 break; 127 if(cur[u]!=-1) 128 { 129 stack[top++]=cur[u]; 130 u=edge[cur[u]].to; 131 } 132 else 133 { 134 if(top==0)break; 135 dep[u]=-1; 136 u=edge[stack[--top]].from; 137 } 138 } 139 } 140 return res; 141 } 142 143 struct node { 144 int x, y; 145 }q[MAXN*MAXN]; 146 147 int findset(int x) 148 { 149 return fa[x] = fa[x] == x?x:findset(fa[x]); 150 } 151 152 void merg(int a, int b) 153 { 154 int x = findset(a); 155 int y = findset(b); 156 if (x != y) 157 fa[x] = y; 158 } 159 160 bool ok(int mid) 161 { 162 init(); 163 for (int i = 1;i <= n; ++ i) { 164 addedge(st, i, mid); 165 addedge(n+i, en, mid); 166 } 167 for (int i = 0;i < m; ++ i) { 168 int u = q[i].x; 169 int v = q[i].y; 170 for (int j = 1;j <= n; ++ j) { 171 if (findset(u) == findset(j) && !match[j][v]) { 172 match[j][v] = 1; 173 addedge(j, n+v, 1); 174 } 175 } 176 } 177 return (dinic(st, en) >= n*mid); 178 } 179 180 int main() 181 { 182 scanf("%d", &T); 183 while (T--) { 184 scanf("%d%d%d", &n, &m, &k); 185 for (int i = 1;i <= n;++ i) 186 fa[i] = i; 187 int x, y; 188 for (int i = 0;i < m; ++ i) { 189 scanf("%d%d", &q[i].x, &q[i].y); 190 } 191 for (int i = 0;i < k; ++ i) { 192 scanf("%d%d", &x, &y); 193 merg(x, y); 194 } 195 st = 0, en = n*2+1; 196 int l = 0, r = n; 197 int ans = 0; 198 while (l <= r) { 199 int mid = (l+r)>>1; 200 if (ok(mid)) { 201 ans = mid; 202 l = mid+1; 203 } 204 else r = mid-1; 205 } 206 cout << ans << endl; 207 } 208 return 0; 209 }
3277 Marriage Match III(中等,好题) [二分最大流]同上,多了拆点
3416 Marriage Match IV(中等,好题) [最大流]最短路+最大流2485Destroying the bus stations [最大流]最短路+最大流 [已验证最大流解法是错的]
3468 Treasure Hunting(中等) [最大流](二分匹配)+最短路
3998 Sequence(较难) [DP+最大流]最长上升子序列
4309 Seikimatsu Occult Tonneru(中等) [最大流]枚举状态+最大流
3472 HS BDC(难) [混合欧拉]
----------------------------------------------------------------------------------------------
1533 Going Home(入门题) [费用流]
3488 Tour(基础) [费用流]圈
1 /*Author :usedrose */ 2 /*Created Time :2015/8/30 1:20:31*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define OK cout << "ok" << endl; 24 #define o(a) cout << #a << " = " << a << endl 25 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 26 using namespace std; 27 typedef long long LL; 28 29 const int N = 310; 30 const int INF = 0x3f3f3f3f; 31 int nx, ny;//两边的点数 32 int g[N][N];//二分图描述 33 int linker[N],lx[N],ly[N];//y中各点匹配状态, x,y中的点标号 34 int slack[N]; 35 bool visx[N],visy[N]; 36 bool DFS(int x) 37 { 38 visx[x] = true; 39 for(int y = 0; y < ny; y++) { 40 if(visy[y])continue; 41 int tmp = lx[x] + ly[y] - g[x][y]; 42 if(tmp == 0) { 43 visy[y] = true; 44 if(linker[y] == -1 || DFS(linker[y])) { 45 linker[y] = x; 46 return true; 47 } 48 } 49 else if(slack[y] > tmp) 50 slack[y] = tmp; 51 } 52 return false; 53 } 54 55 int KM() 56 { 57 memset(linker,-1,sizeof(linker)); 58 memset(ly,0,sizeof(ly)); 59 for(int i = 0;i < nx;i++) { 60 lx[i] = -INF; 61 for(int j = 0;j < ny;j++) 62 if(g[i][j] > lx[i]) 63 lx[i] = g[i][j]; 64 } 65 for(int x = 0;x < nx;x++) { 66 for(int i = 0;i < ny;i++) 67 slack[i] = INF; 68 while(true) { 69 memset(visx,false,sizeof(visx)); 70 memset(visy,false,sizeof(visy)); 71 if(DFS(x))break; 72 int d = INF; 73 for(int i = 0;i < ny;i++) 74 if(!visy[i] && d > slack[i]) 75 d = slack[i]; 76 for(int i = 0;i < nx;i++) 77 if(visx[i]) 78 lx[i] -= d; 79 for(int i = 0;i < ny;i++) { 80 if(visy[i])ly[i] += d; 81 else slack[i] -= d; 82 } 83 } 84 } 85 int res = 0; 86 for(int i = 0;i < ny;i++) 87 if(linker[i] != -1) 88 res += g[linker[i]][i]; 89 return -res; 90 } 91 92 int main() 93 { 94 int T, n, m, x, y, w; 95 scanf("%d", &T); 96 while(T-- ) { 97 scanf("%d%d", &n, &m); 98 nx = ny = n; 99 memset(g, 0x80, sizeof(g)); 100 for (int i = 1;i <= m; ++ i) { 101 scanf("%d%d%d", &x, &y, &w); 102 x--, y--; 103 g[x][y] = max(g[x][y], -w); 104 } 105 printf("%d ",KM()); 106 } 107 return 0; 108 }
3435 A new Graph Game(基础) [费用流]圈 。。。 自己写的那版T到死。。 我要炸了!
1 /*Author :usedrose */ 2 /*Created Time :2015/9/1 20:55:20*/ 3 /*File Name :3.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define OK cout << "ok" << endl; 24 #define o(a) cout << #a << " = " << a << endl 25 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 26 using namespace std; 27 typedef long long LL; 28 #define inf 999999999 29 struct node 30 { 31 int u,v,f,c; 32 }; 33 node e[60000]; 34 int first[3000],nxt[60000],cc; 35 int p[3000],preedge[3000],d[3000],ans_flow,ans_cost; 36 inline void addedge(int u,int v,int f,int c) 37 { 38 e[cc].u=u; 39 e[cc].v=v; 40 e[cc].f=f; 41 e[cc].c=c; 42 nxt[cc]=first[u]; 43 first[u]=cc; 44 cc++; 45 46 e[cc].v=u; 47 e[cc].u=v; 48 e[cc].f=0; 49 e[cc].c=-c; 50 nxt[cc]=first[v]; 51 first[v]=cc; 52 cc++; 53 } 54 bool spfa(int s,int t) 55 { 56 int inq[3000]; 57 memset(inq,0,sizeof(inq)); 58 memset(p,-1,sizeof(p)); 59 memset(preedge,-1,sizeof(preedge)); 60 int i; 61 for(i=0;i<=t;i++) 62 d[i]=inf; 63 d[s]=0; 64 queue<int> q; 65 q.push(s); 66 while(!q.empty()) 67 { 68 int u=q.front(); 69 q.pop(); 70 inq[u]=0; 71 for(i=first[u];i!=-1;i=nxt[i]) 72 { 73 if(e[i].f) 74 { 75 int v=e[i].v; 76 if(d[v]>d[u]+e[i].c) 77 { 78 d[v]=d[u]+e[i].c; 79 p[v]=u; 80 preedge[v]=i; 81 if(!inq[v]) 82 { 83 inq[v]=1; 84 q.push(v); 85 } 86 } 87 } 88 } 89 } 90 if(d[t]>=inf) 91 return false; 92 else 93 return true; 94 } 95 void min_cost_flow(int s,int t) 96 { 97 ans_cost=0;ans_flow=0; 98 while(spfa(s,t)) 99 { 100 int u=t; 101 int mm=inf; 102 while(p[u]!=-1) 103 { 104 mm=min(mm,e[preedge[u]].f); 105 u=p[u]; 106 } 107 u=t; 108 while(p[u]!=-1) 109 { 110 e[preedge[u]].f-=mm; 111 e[preedge[u]^1].f+=mm; 112 u=p[u]; 113 } 114 ans_cost+=mm*d[t]; 115 ans_flow+=mm; 116 } 117 } 118 119 120 121 int main() 122 { 123 int T,n, m; 124 scanf("%d", &T); 125 for (int ncase = 1;ncase <= T; ++ ncase) { 126 scanf("%d%d", &n, &m); 127 int x, y, w; 128 int i, s = 0, t = 2*n+1; 129 memset(first, -1, sizeof(first)); 130 memset(nxt, -1, sizeof(nxt)); 131 cc = 0; 132 for (i = 1;i <= n; ++ i) { 133 addedge(s, i, 1, 0); 134 addedge(n+i, t, 1, 0); 135 } 136 for (i = 1;i <= m; ++ i) { 137 scanf("%d%d%d", &x, &y, &w); 138 addedge(x, n + y, 1, w); 139 addedge(y, n + x, 1, w); 140 } 141 min_cost_flow(s, t); 142 if (ans_flow < n) 143 printf("Case %d: NO ", ncase); 144 else 145 printf("Case %d: %d ", ncase, ans_cost); 146 } 147 return 0; 148 }
1853 Cyclic Tour(基础) [费用流]圈
2686 Matrix(基础) [费用流]
3376 Matrix Again(基础) [费用流]
3667 Transportation(中等) [费用流]拆边
1 /*Author :usedrose */ 2 /*Created Time :2015/9/2 8:40:46*/ 3 /*File Name :3.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 220; 30 const int MAXM = 500010; 31 int n,m; 32 33 struct Edge 34 { 35 int to,next,cap,flow,cost; 36 }edge[MAXM]; 37 int head[MAXN],tol; 38 int pre[MAXN],dis[MAXN]; 39 bool vis[MAXN]; 40 int N;//节点总个数,节点编号从0~N-1 41 42 void init(int n) 43 { 44 N = n; 45 tol = 0; 46 memset(head,-1,sizeof(head)); 47 } 48 49 void addedge(int u,int v,int cap,int cost) 50 { 51 edge[tol].to = v; 52 edge[tol].cap = cap; 53 edge[tol].cost = cost; 54 edge[tol].flow = 0; 55 edge[tol].next = head[u]; 56 head[u] = tol++; 57 edge[tol].to = u; 58 edge[tol].cap = 0; 59 edge[tol].cost = -cost; 60 edge[tol].flow = 0; 61 edge[tol].next = head[v]; 62 head[v] = tol++; 63 } 64 65 bool spfa(int s,int t) 66 { 67 queue<int>q; 68 for(int i = 0;i < N;i++) 69 { 70 dis[i] = INF; 71 vis[i] = false; 72 pre[i] = -1; 73 } 74 dis[s] = 0; 75 vis[s] = true; 76 q.push(s); 77 while(!q.empty()) 78 { 79 int u = q.front(); 80 q.pop(); 81 vis[u] = false; 82 for(int i = head[u]; i != -1;i = edge[i].next) 83 { 84 int v = edge[i].to; 85 if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) 86 { 87 dis[v] = dis[u] + edge[i].cost; 88 pre[v] = i; 89 if(!vis[v]) 90 { 91 vis[v] = true; 92 q.push(v); 93 } 94 } 95 } 96 } 97 if(pre[t] == -1) return false; 98 else return true; 99 } 100 101 //返回的是最大流, cost存的是最小费用 102 int mcmf(int s,int t,int &cost) 103 { 104 int flow = 0; 105 cost = 0; 106 while(spfa(s,t)) 107 { 108 int Min = INF; 109 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 110 { 111 if(Min > edge[i].cap - edge[i].flow) 112 Min = edge[i].cap - edge[i].flow; 113 } 114 flow += Min; 115 //cost += Min*(dis[t]); 116 for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) 117 { 118 edge[i].flow += Min; 119 edge[i^1].flow -= Min; 120 cost += edge[i].cost * Min; 121 } 122 } 123 return flow; 124 } 125 126 int main() 127 { 128 cin.tie(0); 129 ios::sync_with_stdio(false); 130 int K, x, y, w, c; 131 while (cin >> n >> m >> K) { 132 init(n+2); 133 for (int i = 1;i <= m; ++ i) { 134 cin >> x >> y >> c >> w; 135 for (int j = 1;j <= w; ++ j) 136 addedge(x, y, 1, c*(2*j-1)); 137 } 138 int cost = 0; 139 addedge(0, 1, K, 0); 140 addedge(n, n+1, K, 0); 141 int ans = mcmf(0, n+1, cost); 142 if (ans == K) 143 cout << cost << endl; 144 else 145 cout << -1 << endl; 146 } 147 return 0; 148 }
3315 My Brute(中等,好题) [费用流](可用KM)
3395 Special Fish(中等,好题) [费用流](可用KM匹配)
2448 Mining Station on the Sea(中等) [费用流](可用最短路+KM匹配)
4067 Random Maze(难) [费用流]
3947 River Problem(难) [费用流]神奇费用流,流量不等式建图
4406 GPA [好题] [官方题解为所谓的上下界费用流]
4411 Arrest [好题] [官方题解为所谓的上下界费用流]
---------------------------------------------------------------------------------------------
3046 Pleasant sheep and big big wolf(入门题) [最小割]
1565 方格取数(1)(基础) [最小割]黑白染色
1569 方格取数(2)(基础) [最小割]黑白染色
3820 Golden Eggs(较难,好题) [最小割]方格加强
3491 Thieves(中等) [最小割]最小点割集
1 /*Author :usedrose */ 2 /*Created Time :2015/9/3 18:44:51*/ 3 /*File Name :3.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 220; 30 const int MAXM = 100010; 31 int n, m, T; 32 int st, en; 33 34 struct Node 35 { 36 int from,to,next; 37 int cap; 38 }edge[MAXM]; 39 int tol; 40 41 int dep[MAXN];//dep为点的层次 42 int head[MAXN]; 43 44 void init() 45 { 46 tol=0; 47 memset(head,-1,sizeof(head)); 48 } 49 void addedge(int u,int v,int w)//第一条变下标必须为偶数 50 { 51 edge[tol].from=u; 52 edge[tol].to=v; 53 edge[tol].cap=w; 54 edge[tol].next=head[u]; 55 head[u]=tol++; 56 edge[tol].from=v; 57 edge[tol].to=u; 58 edge[tol].cap=0; 59 edge[tol].next=head[v]; 60 head[v]=tol++; 61 } 62 63 int BFS(int start,int end) 64 { 65 int que[MAXN]; 66 int front,rear; 67 front=rear=0; 68 memset(dep,-1,sizeof(dep)); 69 que[rear++]=start; 70 dep[start]=0; 71 while(front!=rear) 72 { 73 int u=que[front++]; 74 if(front==MAXN)front=0; 75 for(int i=head[u];i!=-1;i=edge[i].next) 76 { 77 int v=edge[i].to; 78 if(edge[i].cap>0&&dep[v]==-1) 79 { 80 dep[v]=dep[u]+1; 81 que[rear++]=v; 82 if(rear>=MAXN)rear=0; 83 if(v==end)return 1; 84 } 85 } 86 } 87 return 0; 88 } 89 int dinic(int start,int end) 90 { 91 int res=0; 92 int top; 93 int stack[MAXN];//stack为栈,存储当前增广路 94 int cur[MAXN];//存储当前点的后继 95 while(BFS(start,end)) 96 { 97 memcpy(cur,head,sizeof(head)); 98 int u=start; 99 top=0; 100 while(1) 101 { 102 if(u==end) 103 { 104 int min=INF; 105 int loc; 106 for(int i=0;i<top;i++) 107 if(min>edge[stack[i]].cap) 108 { 109 min=edge[stack[i]].cap; 110 loc=i; 111 } 112 for(int i=0;i<top;i++) 113 { 114 edge[stack[i]].cap-=min; 115 edge[stack[i]^1].cap+=min; 116 } 117 res+=min; 118 top=loc; 119 u=edge[stack[top]].from; 120 } 121 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 122 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 123 break; 124 if(cur[u]!=-1) 125 { 126 stack[top++]=cur[u]; 127 u=edge[cur[u]].to; 128 } 129 else 130 { 131 if(top==0)break; 132 dep[u]=-1; 133 u=edge[stack[--top]].from; 134 } 135 } 136 } 137 return res; 138 } 139 140 int main() 141 { 142 cin >> T; 143 int s, h; 144 while (T--) { 145 scanf("%d%d%d%d", &n, &m, &s, &h); 146 init(); 147 int x, y; 148 for (int i = 1;i <= n; ++ i) { 149 scanf("%d", &x); 150 addedge(i, i +n, x); 151 } 152 //m条无向边 153 for (int i = 0;i < m; ++ i) { 154 scanf("%d%d", &x, &y); 155 addedge(x+n, y, INF); 156 addedge(y+n, x, INF); 157 } 158 st = 0, en = 2*n+1; 159 addedge(st, s, INF); 160 addedge(s, s+n, INF); 161 addedge(h, h+n, INF); 162 addedge(n+h, en, INF); 163 printf("%d ", dinic(st, en)); 164 } 165 return 0; 166 }
3657 Game(中等) [最小割]最大点权独立集
3313 Key Vertex(中等) [最小割]
3251 Being a Hero(中等) [最小割]
3452 Bonsai(基础) [最小割]一颗带边权的树,最小割求树根和叶子结点不连通
3987 Harry Potter and the Forbidden Forest(较难,好题) [最小割]最小割的情况下,求最少需要割掉多少条边.
C++过的。。G++RE。。
1 /*Author :usedrose */ 2 /*Created Time :2015/9/3 18:44:51*/ 3 /*File Name :3.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 2020; 30 const int MAXM = 2000010; 31 int n, m, T; 32 int st, en; 33 34 struct Node 35 { 36 int from,to,next; 37 LL cap; 38 }edge[MAXM]; 39 int tol; 40 41 int dep[MAXN];//dep为点的层次 42 int head[MAXN]; 43 44 void init() 45 { 46 tol=0; 47 memset(head,-1,sizeof(head)); 48 } 49 void addedge(int u,int v,LL w)//第一条变下标必须为偶数 50 { 51 edge[tol].from=u; 52 edge[tol].to=v; 53 edge[tol].cap=w; 54 edge[tol].next=head[u]; 55 head[u]=tol++; 56 edge[tol].from=v; 57 edge[tol].to=u; 58 edge[tol].cap=0; 59 edge[tol].next=head[v]; 60 head[v]=tol++; 61 } 62 63 int BFS(int start,int end) 64 { 65 int que[MAXN]; 66 int front,rear; 67 front=rear=0; 68 memset(dep,-1,sizeof(dep)); 69 que[rear++]=start; 70 dep[start]=0; 71 while(front!=rear) 72 { 73 int u=que[front++]; 74 if(front==MAXN)front=0; 75 for(int i=head[u];i!=-1;i=edge[i].next) 76 { 77 int v=edge[i].to; 78 if(edge[i].cap>0&&dep[v]==-1) 79 { 80 dep[v]=dep[u]+1; 81 que[rear++]=v; 82 if(rear>=MAXN)rear=0; 83 if(v==end)return 1; 84 } 85 } 86 } 87 return 0; 88 } 89 90 LL dinic(int start,int end) 91 { 92 LL res=0; 93 int top; 94 int stack[MAXN];//stack为栈,存储当前增广路 95 int cur[MAXN];//存储当前点的后继 96 while(BFS(start,end)) 97 { 98 memcpy(cur,head,sizeof(head)); 99 int u=start; 100 top=0; 101 while(1) 102 { 103 if(u==end) 104 { 105 LL min=INF; 106 int loc; 107 for(int i=0;i<top;i++) 108 if(min>edge[stack[i]].cap) 109 { 110 min=edge[stack[i]].cap; 111 loc=i; 112 } 113 for(int i=0;i<top;i++) 114 { 115 edge[stack[i]].cap-=min; 116 edge[stack[i]^1].cap+=min; 117 } 118 res+=min; 119 top=loc; 120 u=edge[stack[top]].from; 121 } 122 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 123 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 124 break; 125 if(cur[u]!=-1) 126 { 127 stack[top++]=cur[u]; 128 u=edge[cur[u]].to; 129 } 130 else 131 { 132 if(top==0)break; 133 dep[u]=-1; 134 u=edge[stack[--top]].from; 135 } 136 } 137 } 138 return res; 139 } 140 141 int main() 142 { 143 scanf("%d", &T); 144 int ncase = 1; 145 while (T--) { 146 scanf("%d%d", &n, &m); 147 init(); 148 st = 0, en = n-1; 149 int u, v, f, w; 150 for (int i = 0;i < m; ++ i) { 151 scanf("%d%d%d%d", &u, &v, &w, &f); 152 addedge(u, v, (LL)w*MAXM+1); 153 if (f) addedge(v, u, (LL)w*MAXM+1); 154 } 155 LL ans = dinic(st, en); 156 printf("Case %d: %lld ", ncase++, (ans%MAXM)); 157 } 158 return 0; 159 }
2435 There is a war(较难,好题) [最小割]打造无敌桥
1 /*Author :usedrose */ 2 /*Created Time :2015/9/3 18:44:51*/ 3 /*File Name :3.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 const int MAXN = 120; 30 const int MAXM = 10010; 31 int n, m, T; 32 int st, en; 33 34 struct Node 35 { 36 int from,to,next; 37 int cap; 38 }edge[MAXM]; 39 int tol; 40 41 int dep[MAXN];//dep为点的层次 42 int head[MAXN]; 43 bool vis[MAXN]; 44 void init() 45 { 46 tol=0; 47 memset(vis, 0, sizeof(vis)); 48 memset(head,-1,sizeof(head)); 49 } 50 void addedge(int u,int v,int w)//第一条变下标必须为偶数 51 { 52 edge[tol].from=u; 53 edge[tol].to=v; 54 edge[tol].cap=w; 55 edge[tol].next=head[u]; 56 head[u]=tol++; 57 edge[tol].from=v; 58 edge[tol].to=u; 59 edge[tol].cap=0; 60 edge[tol].next=head[v]; 61 head[v]=tol++; 62 } 63 64 int BFS(int start,int end) 65 { 66 int que[MAXN]; 67 int front,rear; 68 front=rear=0; 69 memset(dep,-1,sizeof(dep)); 70 que[rear++]=start; 71 dep[start]=0; 72 while(front!=rear) 73 { 74 int u=que[front++]; 75 if(front==MAXN)front=0; 76 for(int i=head[u];i!=-1;i=edge[i].next) 77 { 78 int v=edge[i].to; 79 if(edge[i].cap>0&&dep[v]==-1) 80 { 81 dep[v]=dep[u]+1; 82 que[rear++]=v; 83 if(rear>=MAXN)rear=0; 84 if(v==end)return 1; 85 } 86 } 87 } 88 return 0; 89 } 90 91 int dinic(int start,int end) 92 { 93 int res=0; 94 int top; 95 int stack[MAXN];//stack为栈,存储当前增广路 96 int cur[MAXN];//存储当前点的后继 97 while(BFS(start,end)) 98 { 99 memcpy(cur,head,sizeof(head)); 100 int u=start; 101 top=0; 102 while(1) 103 { 104 if(u==end) 105 { 106 int min=INF; 107 int loc; 108 for(int i=0;i<top;i++) 109 if(min>edge[stack[i]].cap) 110 { 111 min=edge[stack[i]].cap; 112 loc=i; 113 } 114 for(int i=0;i<top;i++) 115 { 116 edge[stack[i]].cap-=min; 117 edge[stack[i]^1].cap+=min; 118 } 119 res+=min; 120 top=loc; 121 u=edge[stack[top]].from; 122 } 123 for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) 124 if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to]) 125 break; 126 if(cur[u]!=-1) 127 { 128 stack[top++]=cur[u]; 129 u=edge[cur[u]].to; 130 } 131 else 132 { 133 if(top==0)break; 134 dep[u]=-1; 135 u=edge[stack[--top]].from; 136 } 137 } 138 } 139 return res; 140 } 141 142 void gao() 143 { 144 int ans = dinic(st, en); 145 queue<int> q; 146 vis[st] = 1; 147 q.push(st); 148 while (!q.empty()) { 149 int t = q.front(); 150 q.pop(); 151 for (int i = head[t];i != -1;i = edge[i].next) { 152 int v = edge[i].to; 153 if (!vis[v] && edge[i].cap > 0) { 154 vis[v] = 1; 155 q.push(v); 156 } 157 } 158 } 159 vector<Node> rem; 160 for (int i = 0;i < tol; ++ i) rem.push_back(edge[i]); 161 int tmp = 0; 162 for (int i = 2;i < n; ++ i) 163 for (int j = 2;j < n; ++ j) { 164 if (vis[i] && (!vis[j])) { 165 int h1 = head[i], h2 = head[j]; 166 addedge(i, j, INF); 167 int t = dinic(st, en); 168 tmp = max(tmp, t); 169 tol -= 2; 170 head[i] = h1, head[j] = h2; 171 for (int k = 0;k < tol; ++ k) edge[k] = rem[k]; 172 } 173 } 174 printf("%d ", ans + tmp); 175 } 176 177 int main() 178 { 179 scanf("%d", &T); 180 while (T--) { 181 scanf("%d%d", &n, &m); 182 init(); 183 st = 1, en = n; 184 int u, v, w; 185 for (int i = 0;i < m; ++ i) { 186 scanf("%d%d%d", &u, &v, &w); 187 addedge(u, v, w); 188 } 189 gao(); 190 } 191 return 0; 192 }
3917 Road constructions(中等) [最大权闭包]最大获利
3879 Base Station(中等) [最大权闭包]最大获利
3061 Battle(中等) [最大权闭包]最大获利
3996 Gold Mine(中等) [最大权闭包]最大获利
4307 Matrix(较难,好题) [最小割][项目分配问题]
4265 Science! (较难)
4289 Control(中等) [最小点权覆盖]
4292 Food(基础) [最大流]
4322 Candy(难) [好题][最大流]