首页 > 代码库 > 下界最小费用最大流

下界最小费用最大流

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("\n");
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\n",ee);
79     for(int i=2;i<=ee;i++) printf("%d %d %d\n",vs[i].v,vs[i].w,vs[i].c); */
80     while(spfa()) mcf();
81     printf("%d\n",ans);
82     return 0;
83 }
View Code

 

下界最小费用最大流