hdu 2485(最小费用最大流)

题目链接: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<<30

10 

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

 

你可能感兴趣的:(HDU)