BZOJ 1927 SDOI2010 星际竞速 最小费用最大流

  中文题面,还特长。请各位自行品尝→星际竞速

分析:

  首先拆穿题面一个伪装。题面里竟然明摆着说是双向图,后来又变成了“只能由每个星球飞往引力比它大的星球”,所以这就是出题人凑字数的把戏,我们直接将其看作单向边就好了(不过如果给的顺序反了要swap一下)

  这个题目的图比较好建,比起那些奇奇怪怪的转化,我们只需要按着题面建图就好了。

  我们要满足“每个点恰好访问一次”这个限制,在求最小费用的题目里,我们应该用最大流来保证这种限制(就是说,当全图为最大流时,即为访问每个点恰好一次)

  我们按照在这个思路去建图。将每个星球拆成一个入点和一个出点

  从原点S向每个星球的入点连一条容量为1费用为0的边。

  从原点向每个点的出点连一条容量为1费用为瞬移定位时间的边(表示不走寻常路的流?)

  假如在原图中存在(x->y)的一条边,那么我们从x的入点向y的出点连容量为1费用为航路所需时间的边(表示从x点走向了y点完成了这条航道的使命?)

  最小费用最大流,输出费用,结束。

代码:

 1 #include<bits/stdc++.h>
 2 #define ms(a,x) memset(a,x,sizeof(a))
 3 using namespace std;
 4 const int N=5000,M=100000;
 5 const int inf=0x3f3f3f3f;
 6 queue<int>q;int c1[N],c2[N],cnt;
 7 struct node{int y,z,f,nxt;}e[M];
 8 int lst[N],pre[N],S,T;bool vis[N];
 9 int h[N],c=1,n,m,d[N],f[N],ans,tot;
10 void add(int x,int y,int l,int z){
11     e[++c]=(node){y,z,l,h[x]};h[x]=c;
12     e[++c]=(node){x,-z,0,h[y]};h[y]=c;
13 } bool spfa(){
14     for(int i=S;i<=T;i++) pre[i]=-1,
15     f[i]=inf,lst[i]=vis[i]=0,d[i]=inf;
16     q.push(S);d[S]=0;pre[S]=0;
17     while(q.size()){
18         int x=q.front();q.pop();vis[x]=0;
19         for(int i=h[x],y;~i;i=e[i].nxt)
20         if(d[y=e[i].y]>d[x]+e[i].z&&e[i].f){
21             d[y]=d[x]+e[i].z;pre[y]=x;lst[y]=i;
22             f[y]=min(f[x],e[i].f);
23             if(!vis[y]) vis[y]=1,q.push(y);
24         }
25     } return (pre[T]!=-1);
26 } void solve(){
27     while(spfa()){
28         ans+=d[T]*f[T];int x=T;
29         while(x) e[lst[x]].f-=f[T],
30         e[lst[x]^1].f+=f[T],x=pre[x];
31     } return ;
32 } int main(){ ms(h,-1);
33     scanf("%d%d",&n,&m);S=0;cnt=0;
34     for(int i=1;i<=n;i++) 
35     c1[i]=++cnt,c2[i]=++cnt;T=++cnt;
36     for(int i=1,x;i<=n;i++)
37     scanf("%d",&x),add(S,c2[i],1,x);
38     for(int i=1;i<=n;i++) add(S,c1[i],1,0);
39     for(int i=1;i<=n;i++) add(c2[i],T,1,0);
40     for(int i=1,x,y,z;i<=m;i++){
41         scanf("%d%d%d",&x,&y,&z);if(x>y)
42         swap(x,y);add(c1[x],c2[y],1,z);
43     } solve();
44     printf("%d\n",ans);return 0;
45 }
费用流

猜你喜欢

转载自www.cnblogs.com/Alan-Luo/p/10250294.html
今日推荐