题目大意见http://pan.baidu.com/s/1o6zajc2
用Dijkstra跑出最短路图,然后拆点跑网络流即可
这水题我TM还WA了两次是不是省选要滚粗了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010 #define S 0 #define T (M-1) #define INF 0x3f3f3f3f3f3f3f3fll #define P1(x) ((x)*2-1) #define P2(x) ((x)<<1) using namespace std; int n,m; namespace Origin_Graph{ struct abcd{ int to,next; long long f; }table[100100<<1]; int head[M],tot; long long f[M],g[M]; void Add(int x,int y,long long z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void Dijkstra(long long f[],int s) { static bool v[M]; int i,j,k; memset(f,0x3f,sizeof(f[0])*M); memset(v,0,sizeof v); f[s]=0; for(i=1;i<=n;i++) { long long temp=INF; for(j=1;j<=n;j++) if(!v[j]&&f[j]<=temp) temp=f[j],k=j; v[k]=true; for(j=head[k];j;j=table[j].next) f[table[j].to]=min(f[table[j].to],f[k]+table[j].f); } } } namespace Max_Flow{ struct abcd{ int to,next; long long f; }table[100100<<1]; int head[M],tot=1; int dpt[M]; void Add(int x,int y,long long z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void Link(int x,int y,long long z) { Add(x,y,z); Add(y,x,0); } bool BFS() { static int q[M]; int i,r=0,h=0; memset(dpt,-1,sizeof dpt); dpt[S]=1;q[++r]=S; while(r!=h) { int x=q[++h]; for(i=head[x];i;i=table[i].next) if(table[i].f&&!~dpt[table[i].to]) { dpt[table[i].to]=dpt[x]+1; q[++r]=table[i].to; if(table[i].to==T) return true; } } return false; } long long Dinic(int x,long long flow) { int i;long long left=flow; if(x==T) return flow; for(i=head[x];i&&left;i=table[i].next) if(table[i].f&&dpt[table[i].to]==dpt[x]+1) { long long temp=Dinic(table[i].to,min(left,table[i].f)); left-=temp; table[i].f-=temp; table[i^1].f+=temp; } if(left) dpt[x]=-1; return flow-left; } } int main() { using namespace Origin_Graph; int i,x,y,z; cin>>n>>m; for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z);Add(y,x,z); } Dijkstra(f,1); Dijkstra(g,n); for(x=1;x<=n;x++) for(i=head[x];i;i=table[i].next) if(f[x]+table[i].f+g[table[i].to]==f[n]) Max_Flow::Link(P2(x),P1(table[i].to),INF); for(i=1;i<=n;i++) { scanf("%d",&x); Max_Flow::Link(P1(i),P2(i),x); } Max_Flow::Link(S,P2(1),INF); Max_Flow::Link(P1(n),T,INF); long long ans=0; while( Max_Flow::BFS() ) ans+=Max_Flow::Dinic(S,INF); cout<<ans<<endl; return 0; }
时间: 2024-10-12 14:31:29