bzoj 3876 支线任务
对于每一条边(x->y) 费用为z: S-> y 流量为1 费用为z 表示必须经过此边
x-> y 流量为inf 费用为z 表示除此以外还可以随意走动
对于每一个点 x x-> T 流量为 x的出度 费用为0
x-> 1 流量为 inf 费用为0 对应题目中的初始点 可以返回
另看到有很多人 都只跑了100多ms 这是什么高明的做法求解 QAQ 还是 too naive
1 #include <bits/stdc++.h> 2 #define N 310 3 #define M 50000 4 #define inf 0x7fffffff 5 using namespace std; 6 7 inline int read() 8 { 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 struct edge 15 { 16 int u,v,w; 17 int next,c; 18 }vs[M]; 19 20 int n,ee=1,st[N],from[N],S,T; 21 int ans=0,vis[N],dis[N],p[N]; 22 queue <int> q; 23 inline void addedge(int u,int v,int w,int c) 24 { 25 vs[++ee].u=u;vs[ee].v=v;vs[ee].w=w; 26 vs[ee].next=st[u];st[u]=ee;vs[ee].c=c; 27 } 28 inline void insert(int u,int v,int w,int c) 29 { 30 addedge(u,v,w,c);addedge(v,u,0,-c); 31 } 32 bool spfa() 33 { 34 for(int i=S;i<=T;i++) dis[i]=inf; 35 while(!q.empty())q.pop(); 36 q.push(S);dis[S]=0;vis[S]=1; 37 while(!q.empty()) 38 { 39 int lx=q.front();q.pop(); 40 for(int i=st[lx];i;i=vs[i].next) 41 if(vs[i].w&&dis[lx]+vs[i].c<dis[vs[i].v]) 42 { 43 dis[vs[i].v]=dis[lx]+vs[i].c; 44 from[vs[i].v]=lx;p[vs[i].v]=i; 45 if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1; 46 } 47 vis[lx]=0; 48 } 49 // for(int i=S;i<=T;i++) printf("%d ",dis[i]);printf(" "); 50 return dis[T]!=inf; 51 } 52 inline void mcf() 53 { 54 int ss=inf;for(int i=T;i!=S;i=from[i]) 55 ss=min(ss,vs[p[i]].w); 56 for(int i=T;i!=S;i=from[i]) 57 { 58 vs[p[i]].w-=ss;vs[p[i]^1].w+=ss; 59 ans+=ss*vs[p[i]].c; 60 } 61 } 62 int main() 63 { 64 n=read(); 65 S=0;T=n+1; 66 for(int i=1;i<=n;i++) 67 { 68 int k=read(); 69 for(int j=1;j<=k;j++) 70 { 71 int a=read(),b=read(); 72 insert(S,a,1,b); 73 insert(i,a,inf,b); 74 } 75 insert(i,T,k,0); 76 if(i!=1) insert(i,1,inf,0); 77 } 78 /* printf("%d ",ee); 79 for(int i=2;i<=ee;i++) printf("%d %d %d ",vs[i].v,vs[i].w,vs[i].c); */ 80 while(spfa()) mcf(); 81 printf("%d ",ans); 82 return 0; 83 }