zoj 3362(最大费用)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3904

思路:费用流的题,增加一个超级源点和一个超级汇点,然后就是连边了,对于每个城市,与汇点连边,容量为inf,花费(这里指收益)为商品在该城市的价值,然后对于图中给定的边,容量为cap,花费为-cost(负数代表花费),最后就是源点与城市1连边了,然后就是跑费用流了,求最大收益(当dist[vt]<0时直接退出)。

 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 inf 1<<30

 9 

10 struct Edge{

11     int v,cap,cost,next;

12 }edge[MAXN*MAXN];

13 

14 int n,m,vs,vt,NE;

15 int head[MAXN];

16 

17 void Insert(int u,int v,int cap,int cost)

18 {

19     edge[NE].v=v;

20     edge[NE].cap=cap;

21     edge[NE].cost=cost;

22     edge[NE].next=head[u];

23     head[u]=NE++;

24 

25     edge[NE].v=u;

26     edge[NE].cap=0;

27     edge[NE].cost=-cost;

28     edge[NE].next=head[v];

29     head[v]=NE++;

30 }

31 

32 bool mark[MAXN];

33 int dist[MAXN],pre[MAXN],cur[MAXN];

34 bool spfa(int vs,int vt)

35 {

36     memset(mark,false,sizeof(mark));

37     fill(dist,dist+MAXN,-inf);

38     dist[vs]=0;

39     queue<int>que;

40     que.push(vs);

41     while(!que.empty()){

42         int u=que.front();

43         que.pop();

44         mark[u]=false;

45         for(int i=head[u];i!=-1;i=edge[i].next){

46             int v=edge[i].v,cost=edge[i].cost;

47             if(edge[i].cap>0&&dist[u]+cost>dist[v]){

48                 dist[v]=dist[u]+cost;

49                 pre[v]=u;

50                 cur[v]=i;

51                 if(!mark[v]){

52                     mark[v]=true;

53                     que.push(v);

54                 }

55             }

56         }

57     }

58     return dist[vt]>0;

59 }

60 

61 int MinCostFlow(int vs,int vt)

62 {

63     int flow=0,cost=0;

64     while(spfa(vs,vt)){

65         int aug=inf;

66         for(int u=vt;u!=vs;u=pre[u]){

67             aug=min(aug,edge[cur[u]].cap);

68         }

69         flow+=aug,cost+=aug*dist[vt];

70         for(int u=vt;u!=vs;u=pre[u]){

71             edge[cur[u]].cap-=aug;

72             edge[cur[u]^1].cap+=aug;

73         }

74     }

75     return cost;

76 }

77 

78 int main()

79 {

80     int x,u,v,cap,cost;

81     while(~scanf("%d%d",&n,&m)){

82         vs=0,vt=n+1;

83         NE=0;

84         memset(head,-1,sizeof(head));

85         for(int i=2;i<=n;i++){

86             scanf("%d",&x);

87             Insert(i,vt,inf,x);

88         }

89         while(m--){

90             scanf("%d%d%d%d",&u,&v,&cap,&cost);

91             Insert(u,v,cap,-cost);

92             Insert(v,u,cap,-cost);

93         }

94         Insert(vs,1,inf,0);

95         printf("%d\n",MinCostFlow(vs,vt));

96     }

97     return 0;

98 }
View Code

 

你可能感兴趣的:(ZOJ)