Day66:POJ2135-Farm Tour(最小费用最大流模板题)-SPFA+MCMF

题意:

给出n个点,m条边,问一个人从家走到barn的最短长度(设家1,barn为N);
所以,问的就是   去:1->N     和     返:N->1     两条路径的最短长度,两条路径不能重复;
所以,问题变成了:有两个人,从1->N,它们所走路径不能重复(走的边不能重复),求最短长度。

所以变成了最小费用最大流问题,自己再自己想想。

 思路:

我以为是个最短路。。但是最短路貌似好像不能解决路径重复问题叭。。

妥妥的模板,我终于碰到了,原来我先做的都是变形题,我太难了。。

题意转化到算法上还是比较不好想到,怎么分析在上面的题意里面已经写清楚了。

容量cap传入的为1或者2(自己判断传入什么),花费cost即点和点之间的权值。

建边最重要:

扫描二维码关注公众号,回复: 10573730 查看本文章
scanf("%d %d",&n,&m);
tot=0,s=0,t=n+1;
memset(head,-1,sizeof(head));
for(int i=1; i<=m; i++)
{
    int u,v,w;
    scanf("%d %d %d",&u,&v,&w);
    add(u,v,1,w);//cap,cost
    add(v,u,1,w);
}
add(s,1,2,0);
add(n,t,2,0);

邻接表建边:

 1 void add(int u,int v,int cap,int cost)
 2 {
 3     e[tot].to=v;
 4     e[tot].nextt=head[u];
 5     e[tot].cap=cap;
 6     e[tot].cost=cost;
 7     e[tot].flow=0;
 8     head[u]=tot++;
 9 
10     e[tot].to=u;
11     e[tot].nextt=head[v];
12     e[tot].cap=0;
13     e[tot].cost=-cost;
14     e[tot].flow=0;
15     head[v]=tot++;
16 
17 }
View Code

SPFA:

 1 bool SPFA()
 2 {
 3     for(int i=0; i<=t; i++)
 4     {
 5         dist[i]=inf;
 6         book[i]=0;
 7         pre[i]=-1;//head不能放在这里i清,否则为0
 8     }
 9     book[s]=1;
10     dist[s]=0;
11     queue<int>Q;
12     Q.push(s);
13     while(!Q.empty())
14     {
15         int u=Q.front();
16         Q.pop();
17         book[u]=0;
18         for(int i=head[u]; i!=-1; i=e[i].nextt)
19         {
20             int v=e[i].to;
21             if(e[i].cap>e[i].flow&&dist[v]>dist[u]+e[i].cost)
22             {
23                 dist[v]=dist[u]+e[i].cost;
24                 pre[v]=i;
25                 if(book[v]==0)
26                 {
27                     book[v]=1;
28                     Q.push(v);
29                 }
30             }
31         }
32     }
33     if(dist[t]!=inf)
34         return 1;
35     return 0;
36 }
View Code

MCMF:

 1 int MCMF()
 2 {
 3     int flow=0,cost=0;
 4     while(SPFA())
 5     {
 6         int minn=inf;
 7         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
 8             minn=min(minn,e[i].cap-e[i].flow);
 9         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
10         {
11             e[i].flow+=minn;
12             e[i^1].flow-=minn;
13             cost+=e[i].cost*minn;
14         }
15         flow+=minn;
16     }
17     return cost;
18 }
View Code

AC代码:

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<queue>
  4 #include<string.h>
  5 using namespace std;
  6 #define inf 0x3f3f3f3f
  7 
  8 const int N=1010;
  9 bool book[N];
 10 int n,m,tot,s,t,pre[10*N],head[10*N],dist[10*N];
 11 struct node
 12 {
 13     int to,nextt,cap,flow,cost;
 14 } e[N*N];
 15 
 16 void add(int u,int v,int cap,int cost)
 17 {
 18     e[tot].to=v;
 19     e[tot].nextt=head[u];
 20     e[tot].cap=cap;
 21     e[tot].cost=cost;
 22     e[tot].flow=0;
 23     head[u]=tot++;
 24 
 25     e[tot].to=u;
 26     e[tot].nextt=head[v];
 27     e[tot].cap=0;
 28     e[tot].cost=-cost;
 29     e[tot].flow=0;
 30     head[v]=tot++;
 31 
 32 }
 33 
 34 bool SPFA()
 35 {
 36     for(int i=0; i<=t; i++)
 37     {
 38         dist[i]=inf;
 39         book[i]=0;
 40         pre[i]=-1;//head不能放在这里i清,否则为0
 41     }
 42     book[s]=1;
 43     dist[s]=0;
 44     queue<int>Q;
 45     Q.push(s);
 46     while(!Q.empty())
 47     {
 48         int u=Q.front();
 49         Q.pop();
 50         book[u]=0;
 51         for(int i=head[u]; i!=-1; i=e[i].nextt)
 52         {
 53             int v=e[i].to;
 54             if(e[i].cap>e[i].flow&&dist[v]>dist[u]+e[i].cost)
 55             {
 56                 dist[v]=dist[u]+e[i].cost;
 57                 pre[v]=i;
 58                 if(book[v]==0)
 59                 {
 60                     book[v]=1;
 61                     Q.push(v);
 62                 }
 63             }
 64         }
 65     }
 66     if(dist[t]!=inf)
 67         return 1;
 68     return 0;
 69 }
 70 
 71 int MCMF()
 72 {
 73     int flow=0,cost=0;
 74     while(SPFA())
 75     {
 76         int minn=inf;
 77         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
 78             minn=min(minn,e[i].cap-e[i].flow);
 79         for(int i=pre[t]; i!=-1; i=pre[e[i^1].to])
 80         {
 81             e[i].flow+=minn;
 82             e[i^1].flow-=minn;
 83             cost+=e[i].cost*minn;
 84         }
 85         flow+=minn;
 86     }
 87     return cost;
 88 }
 89 
 90 int main()
 91 {
 92     scanf("%d %d",&n,&m);
 93     tot=0,s=0,t=n+1;
 94     memset(head,-1,sizeof(head));
 95     for(int i=1; i<=m; i++)
 96     {
 97         int u,v,w;
 98         scanf("%d %d %d",&u,&v,&w);
 99         add(u,v,1,w);//cap,cost
100         add(v,u,1,w);
101     }
102     add(s,1,2,0);
103     add(n,t,2,0);
104     int ans=MCMF();
105     printf("%d\n",ans);
106     return 0;
107 }
View Code

猜你喜欢

转载自www.cnblogs.com/OFSHK/p/12655707.html