zoukankan      html  css  js  c++  java
  • 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
Copyright © 2011-2022 走看看