hdu 2485(最小费用最大流)

来源:互联网 发布:linux能运行exe文件吗 编辑:程序博客网 时间:2024/06/03 20:55

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2485

思路:题目的意思是删除最少的点使1,n的最短路大于k。将点转化为边,容量为1,费用为0,然后就是对于那些有道路的城市之间连边,若(u,v)有边,则连边(u+n)->v,容量为inf,费用为花费的时间1,然后就是跑最小费了,若dist[vt]>k,则返回false,最后输出的flow就代表要删除的点的个数。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 222 8 #define MAXM 4444444 9 #define inf 1<<3010 11 struct Edge{12     int v,cap,cost,next;13 }edge[MAXM];14 15 int n,m,k,vs,vt,NE;16 int head[MAXN];17 18 void Insert(int u,int v,int cap,int cost)19 {20     edge[NE].v=v;21     edge[NE].cap=cap;22     edge[NE].cost=cost;23     edge[NE].next=head[u];24     head[u]=NE++;25 26     edge[NE].v=u;27     edge[NE].cap=0;28     edge[NE].cost=-cost;29     edge[NE].next=head[v];30     head[v]=NE++;31 }32 33 int dist[MAXN],pre[MAXN],cur[MAXN];34 bool mark[MAXN];35 bool spfa(int vs,int vt)36 {37     memset(mark,false,sizeof(mark));38     fill(dist,dist+2*n+1,inf);39     dist[vs]=0;40     queue<int>que;41     que.push(vs);42     while(!que.empty()){43         int u=que.front();44         que.pop();45         mark[u]=false;46         for(int i=head[u];i!=-1;i=edge[i].next){47             int v=edge[i].v,cost=edge[i].cost;48             if(edge[i].cap>0&&dist[u]+cost<dist[v]){49                 dist[v]=dist[u]+cost;50                 pre[v]=u;51                 cur[v]=i;52                 if(!mark[v]){53                     mark[v]=true;54                     que.push(v);55                 }56             }57         }58     }59     if(dist[vt]>k)return false;60     return dist[vt]!=inf;61 }62 63 int MinCostFlow(int vs,int vt)64 {65     int flow=0,cost=0;66     while(spfa(vs,vt)){67         int aug=inf;68         for(int u=vt;u!=vs;u=pre[u]){69             aug=min(aug,edge[cur[u]].cap);70         }71         flow+=aug,cost+=dist[vt]*aug;72         for(int u=vt;u!=vs;u=pre[u]){73             edge[cur[u]].cap-=aug;74             edge[cur[u]^1].cap+=aug;75         }76     }77     return flow;78 }79 80 int main()81 {82     int u,v;83     while(~scanf("%d%d%d",&n,&m,&k)){84         if(n==0&&m==0&&k==0)break;85         NE=0;86         vs=1,vt=n;87         memset(head,-1,sizeof(head));88         for(int i=2;i<=n-1;i++)Insert(i,i+n,1,0);89         while(m--){90             scanf("%d%d",&u,&v);91             if(u==vs)Insert(vs,v,inf,1);92             else Insert(u+n,v,inf,1);93         }94         printf("%d\n",MinCostFlow(vs,vt));95     }96     return 0;97 }
View Code

 

0 0
原创粉丝点击