hdu 网络流题集

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 }
View Code

 最小费用最大流

  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 }
View Code

【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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

3917 Road constructions(中等)    [最大权闭包]最大获利
3879 Base Station(中等)    [最大权闭包]最大获利
3061 Battle(中等)    [最大权闭包]最大获利
3996 Gold Mine(中等)    [最大权闭包]最大获利

4307 Matrix(较难,好题)    [最小割][项目分配问题]

4265 Science! (较难)

4289 Control(中等) [最小点权覆盖]

4292 Food(基础) [最大流]

4322 Candy(难) [好题][最大流]

原文地址:https://www.cnblogs.com/usedrosee/p/4763496.html