BZOJ 1497: [NOI2006]最大获利(最大权闭合图)

http://www.lydsy.com/JudgeOnline/problem.php?id=1497

题意:

 

思路:

论文题,只要看过论文的话就是小菜一碟啦~

每个用户群i作为一个结点分别向相应的中转站ai和中转站bi连有向边。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<stack>
  7 #include<queue>
  8 #include<cmath>
  9 #include<map>
 10 #include<set>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef pair<int,int> pll;
 14 const int INF = 0x3f3f3f3f;
 15 const int maxn = 55000 + 5;
 16 
 17 int n, m;
 18 int val[maxn];
 19 
 20 struct Edge
 21 {
 22     int from,to,cap,flow;
 23     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 24 };
 25 
 26 struct Dinic
 27 {
 28     int n,m,s,t;
 29     vector<Edge> edges;
 30     vector<int> G[maxn];
 31     bool vis[maxn];
 32     int cur[maxn];
 33     int d[maxn];
 34 
 35     void init(int n)
 36     {
 37         this->n=n;
 38         for(int i=0;i<n;++i) G[i].clear();
 39         edges.clear();
 40     }
 41 
 42     void AddEdge(int from,int to,int cap)
 43     {
 44         edges.push_back( Edge(from,to,cap,0) );
 45         edges.push_back( Edge(to,from,0,0) );
 46         m=edges.size();
 47         G[from].push_back(m-2);
 48         G[to].push_back(m-1);
 49     }
 50 
 51     bool BFS()
 52     {
 53         queue<int> Q;
 54         memset(vis,0,sizeof(vis));
 55         vis[s]=true;
 56         d[s]=0;
 57         Q.push(s);
 58         while(!Q.empty())
 59         {
 60             int x=Q.front(); Q.pop();
 61             for(int i=0;i<G[x].size();++i)
 62             {
 63                 Edge& e=edges[G[x][i]];
 64                 if(!vis[e.to] && e.cap>e.flow)
 65                 {
 66                     vis[e.to]=true;
 67                     d[e.to]=d[x]+1;
 68                     Q.push(e.to);
 69                 }
 70             }
 71         }
 72         return vis[t];
 73     }
 74 
 75     int DFS(int x,int a)
 76     {
 77         if(x==t || a==0) return a;
 78         int flow=0, f;
 79         for(int &i=cur[x];i<G[x].size();++i)
 80         {
 81             Edge &e=edges[G[x][i]];
 82             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 83             {
 84                 e.flow +=f;
 85                 edges[G[x][i]^1].flow -=f;
 86                 flow +=f;
 87                 a -=f;
 88                 if(a==0) break;
 89             }
 90         }
 91         return flow;
 92     }
 93 
 94     int Maxflow(int s,int t)
 95     {
 96         this->s=s; this->t=t;
 97         int flow=0;
 98         while(BFS())
 99         {
100             memset(cur,0,sizeof(cur));
101             flow +=DFS(s,INF);
102         }
103         return flow;
104     }
105 }DC;
106 
107 int main()
108 {
109     //freopen("in.txt","r",stdin);
110     while(~scanf("%d%d",&n,&m))
111     {
112         int src = 0, dst = n+m+1;
113         DC.init(dst+1);
114         for(int i=1;i<=n;i++)
115         {
116             scanf("%d",&val[i]);
117             DC.AddEdge(i,dst,val[i]);
118         }
119         int sum = 0;
120         for(int i=1;i<=m;i++)
121         {
122             int a,b,c;
123             scanf("%d%d%d",&a,&b,&c);
124             DC.AddEdge(src,i+n,c);
125             DC.AddEdge(i+n,a,INF);
126             DC.AddEdge(i+n,b,INF);
127             sum+=c;
128         }
129         int ans = sum-DC.Maxflow(src,dst);
130         printf("%d\n",ans);
131     }
132     return 0;
133 }

 

posted @ 2017-10-10 17:01  Kayden_Cheung  阅读(205)  评论(0编辑  收藏  举报
//目录