NWERC 2012 Problem A Admiral

一个最小费用最大流的简单建模题;

比赛的时候和小珺合力想到了这个题目的模型;

方法:拆点+边的容量为1

这样就可以保证他们不会在点上和边上相遇了!

感谢刘汝佳大神的模板,让我这个网络流的小白A了这个题。

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 #define maxn 42005
  6 #define inf 99999
  7 using namespace std;
  8 
  9 struct edge
 10 {
 11     int from ,to,cap,flow,cost;
 12 };
 13 
 14 struct mcmf
 15 {
 16     int n,m,s,t;
 17     vector<edge>edges;
 18     vector<int>g[maxn];
 19     int inq[maxn],d[maxn],p[maxn],a[maxn];
 20     void init(int n)
 21     {
 22         this->n=n;
 23         edges.clear();
 24         for(int i=0; i<n; i++)g[i].clear();
 25     }
 26     void addedge(int from,int to,int cap,int cost)
 27     {
 28         edges.push_back((edge){from,to,cap,0,cost});
 29         edges.push_back((edge){to,from,0,0,-cost});
 30         m=edges.size();
 31         g[from].push_back(m-2);
 32         g[to].push_back(m-1);
 33     }
 34     bool bellmamford(int s,int t,int &flow,int& cost)
 35     {
 36         for(int i=0; i<n; i++)d[i]=inf;
 37         memset(inq,0,sizeof inq);
 38         d[s]=0;
 39         inq[s]=1;
 40         p[s]=0;
 41         a[s]=inf;
 42         queue<int>q;
 43         q.push(s);
 44         while(!q.empty())
 45         {
 46             int u=q.front();
 47             q.pop();
 48             inq[u]=0;
 49             for(int i=0; i<g[u].size(); i++)
 50             {
 51                 edge& e=edges[g[u][i]];
 52                 if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
 53                 {
 54                     d[e.to]=d[u]+e.cost;
 55                     p[e.to]=g[u][i];
 56                     a[e.to]=min(a[u],e.cap-e.flow);
 57                     if(!inq[e.to])
 58                     {
 59                         q.push(e.to);
 60                         inq[e.to]=1;
 61                     }
 62                 }
 63             }
 64         }
 65         if(d[t]==inf)return false;
 66         flow+=a[t];
 67         cost+=d[t]*a[t];
 68         int u=t;
 69         while(u!=s)
 70         {
 71             edges[p[u]].flow+=a[t];
 72             edges[p[u]^1].flow-=a[t];
 73             u=edges[p[u]].from;
 74         }
 75         return true;
 76     }
 77 
 78     int mincost(int s,int t)
 79     {
 80         int flow=0,cost=0;
 81         while(bellmamford(s,t,flow,cost));
 82         return cost;
 83     }
 84 }getans;
 85 
 86 int main()
 87 {
 88     int nn,mm,f,t,c;
 89     while(scanf("%d%d",&nn,&mm)!=EOF)
 90     {
 91         getans.init(2*nn+2);
 92         getans.addedge(0,1+nn,2,0);
 93         getans.addedge(nn,2*nn+1,2,0);
 94         for(int i=2;i<nn;i++)
 95             getans.addedge(i,i+nn,1,0);
 96         for(int i=0; i<mm; i++)
 97         {
 98             scanf("%d%d%d",&f,&t,&c);
 99             getans.addedge(f+nn,t,1,c);
100         }
101         printf("%d\n",getans.mincost(0,2*nn+1));
102     }
103     return 0;
104 }
View Code

 

posted @ 2013-10-05 15:59  Yours1103  阅读(221)  评论(0编辑  收藏  举报