洛谷 P1344 [USACO4.4]追查坏牛奶Pollutant Control

https://www.luogu.org/problemnew/show/P1344

题目要求最小割和边数最小的最小割的边数

前者容易,重点是后者

方法:https://blog.csdn.net/chenzhenyu123456/article/details/48103229

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 #include<queue>
  6 #include<iostream>
  7 using namespace std;
  8 #define fi first
  9 #define se second
 10 #define mp make_pair
 11 #define pb push_back
 12 typedef long long ll;
 13 typedef unsigned long long ull;
 14 typedef pair<int,int> pii;
 15 namespace F
 16 {
 17 
 18 struct E
 19 {
 20     int to,nxt,from,cap,flow;
 21 }e[400100];
 22 int f1[60100],ne=1;
 23 int S,T,n;
 24 int d[60100];
 25 bool bfs()
 26 {
 27     int k,u;
 28     memset(d,0,sizeof(int)*(n+1));
 29     queue<int> q;
 30     q.push(S);d[S]=1;
 31     while(!q.empty())
 32     {
 33         u=q.front();q.pop();
 34         for(k=f1[u];k;k=e[k].nxt)
 35             if(!d[e[k].to]&&e[k].cap>e[k].flow)
 36             {
 37                 d[e[k].to]=d[u]+1;
 38                 //if(e[k].to==T)    return 1;
 39                 q.push(e[k].to);
 40             }
 41     }
 42     //return 0;
 43     return d[T];
 44 }
 45 int cur[60100];
 46 int dfs(int u,int x)
 47 {
 48     if(u==T||x==0)    return x;
 49     int flow=0,f;
 50     for(int &k=cur[u];k;k=e[k].nxt)
 51         if(e[k].cap>e[k].flow&&d[e[k].to]==d[u]+1)
 52         {
 53             f=dfs(e[k].to,min(x-flow,e[k].cap-e[k].flow));
 54             e[k].flow+=f;e[k^1].flow-=f;flow+=f;
 55             if(flow==x)    return flow;
 56         }
 57     return flow;
 58 }
 59 int solve()
 60 {
 61     int flow=0;
 62     while(bfs())
 63     {
 64         memcpy(cur,f1,sizeof(int)*(n+1));
 65         flow+=dfs(S,0x3f3f3f3f);
 66     }
 67     return flow;
 68 }
 69 void me(int a,int b,int c)
 70 {
 71     e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
 72     e[ne].from=a;e[ne].cap=c;e[ne].flow=0;
 73     e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
 74     e[ne].from=b;e[ne].cap=0;e[ne].flow=0;
 75 }
 76 
 77 
 78 }
 79 
 80 int n,m;
 81 int main()
 82 {
 83     int i,a,b,c;
 84     scanf("%d%d",&n,&m);F::n=n;F::S=1;F::T=n;
 85     for(i=1;i<=m;i++)
 86     {
 87         scanf("%d%d%d",&a,&b,&c);
 88         F::me(a,b,c);
 89     }
 90     int an=F::solve();
 91     for(i=2;i<=F::ne;i+=2)
 92     {
 93         using F::e;
 94         if(e[i].cap==e[i].flow)
 95         {
 96             e[i].cap=1;e[i^1].cap=0;
 97         }
 98         else
 99         {
100             e[i].cap=0x3f3f3f3f;e[i^1].cap=0;
101         }
102         e[i].flow=0;e[i^1].flow=0;
103     }
104     printf("%d %d",an,F::solve());
105     return 0;
106 }
View Code

 

posted @ 2018-09-14 21:51  hehe_54321  阅读(133)  评论(0编辑  收藏  举报
AmazingCounters.com