BZOJ3931 CQOI2015 网络吞吐量

最短路生成图上跑最大流

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<vector>
  8 
  9 using namespace std;
 10 
 11 #define dout printf
 12 
 13 typedef long long ll;
 14 const int Maxn=1010;
 15 const ll INF=4557430888798830399ll;
 16 int n,m,N;
 17 ll g[Maxn][Maxn];
 18 ll d[Maxn*2];
 19 bool flag[Maxn];
 20 
 21 struct Edge{
 22     int to;
 23     ll cap,flow;
 24     int next;
 25     Edge(int to=0,ll cap=0,int next=0):to(to),cap(cap),next(next){
 26         flow=0;
 27     }
 28     ll adv(){
 29         return cap-flow;
 30     }
 31 }edges[2000010];int tot=1,fir[Maxn*2];
 32 
 33 void AddEdge(int from,int to,ll cap){
 34     edges[++tot]=Edge(to,cap,fir[from]);fir[from]=tot;
 35     edges[++tot]=Edge(from,0,fir[to]);fir[to]=tot;
 36 }
 37 
 38 void init(){
 39     scanf("%d%d",&n,&m);N=2*n;
 40     memset(g,0x3f,sizeof g);
 41     for(int u,v,w,i=1;i<=m;i++){
 42         scanf("%d%d%d",&u,&v,&w);
 43         if(g[u][v]>w) g[u][v]=g[v][u]=w;
 44     }
 45     
 46     for(int c,i=1;i<=n;i++){
 47         scanf("%d",&c);
 48         AddEdge(i,i+n,(i==1||i==n)?INF:c);
 49     }
 50 }
 51 
 52 void Dijkstra(){
 53     memset(d,0x3f,sizeof d);
 54     memset(flag,0,sizeof flag);
 55     d[1]=0;
 56     ll MN;
 57     int u;
 58     for(int T=n;T--;){
 59         MN=INF;
 60         for(int i=1;i<=n;i++) if(!flag[i] && d[i]<MN) {
 61             MN=d[i]; u=i;
 62         }
 63         flag[u]=1;
 64         for(int i=1;i<=n;i++){
 65             d[i]=min(d[i],d[u]+g[u][i]);
 66         }
 67     }
 68 }
 69 
 70 int q[Maxn],ql,qr;
 71 void build(){
 72     q[qr=(ql=0)+1]=n;
 73     memset(flag,0,sizeof flag);
 74     for(;ql<qr;){
 75         int u=q[++ql];
 76         for(int v=1;v<=n;v++)if(u!=v && d[v]+g[u][v]==d[u]){
 77             AddEdge(v+n,u,INF);
 78             if(!flag[v]) q[++qr]=v,flag[v]=1;
 79         }
 80     }
 81 }
 82 
 83 // network-flows begin----------------------------------------------
 84 int s,t;
 85 int p[Maxn*2],cur[Maxn*2],num[Maxn*2];
 86 #define e edges[i]
 87 
 88 inline ll Augment(){
 89     ll a=INF;
 90     for(int x=t;x!=s;x=edges[p[x]^1].to){
 91         a=min(a,edges[p[x]].adv());
 92     }
 93     for(int x=t;x!=s;x=edges[p[x]^1].to){
 94         edges[p[x]].flow+=a;
 95         edges[p[x]^1].flow-=a;
 96     }
 97     return a;
 98 }
 99 inline void BFS(int start,bool flag){
100     for(int i=1;i<=N;i++)d[i]=N;
101     d[q[qr=(ql=0)+1]=start]=0;
102     for(int x;ql<qr;){
103         x=q[++ql];
104         for(int i=fir[x];i;i=e.next){
105             if((flag^(bool)e.adv())&&d[e.to]==N){
106                 d[q[++qr]=e.to]=d[x]+1;
107             }
108         }
109     }
110 }
111 inline ll ISAP(){
112     s=1,t=N;
113     BFS(t,1);
114     ll flow=0;
115     memcpy(cur,fir,sizeof cur);
116     for(int i=1;i<=N;i++)num[d[i]]++;
117     for(int i=1;i<=d[s];i++)if(!num[i])return 0;
118     for(int x=s;d[s]<N;){
119         if(x==t){
120             flow+=Augment();
121             x=s;
122         }
123         int ok=0;
124         for(int&i=cur[x];i;i=e.next){
125             if(e.adv()&&d[x]==d[e.to]+1){
126                 p[x=e.to]=i;
127                 ok=1;
128                 break;
129             }
130         }
131         if(!ok){
132             int M=N;
133             for(int i=fir[x];i;i=e.next){
134                 if(e.adv())M=min(M,(int)d[e.to]+1);
135             }
136             if(!--num[d[x]])break;
137             num[d[x]=M]++;
138             cur[x]=fir[x];
139             if(x!=s)x=edges[p[x]^1].to;
140         }
141     }
142     return flow;
143 }
144 //network-flows end-----------------------------------------------------------
145 
146 int main(){
147     freopen("network.in","r",stdin);
148     freopen("network.out","w",stdout);
149     init();
150     Dijkstra();
151     build();
152     cout<<ISAP();
153     return 0;
154 }
View Code

 

posted @ 2015-04-06 20:35  Showson  阅读(383)  评论(1编辑  收藏  举报