链接:http://poj.org/problem?id=2135
这道题数据范围给的很坑爹啊,题面给的1000,我开到1500都过不了,RE了一个小时,最后实在没办法,开到2000,一下子A了,真想说一句:fuck!!
要求不能有重复的路径,路径的长度为费用,每条路径的流值为1,并且建立超级源点和超级汇点,从超级源点连接到0一个流值为2,费用为0的边,n和超级汇点也连这么一条边,因为是无向图,所以要加四条边,而且只能用邻接表的实现。
剩下的是最小费用流的模板,spfa()找最短路径
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 2005 5 #define M 10005 6 #define inf 1<<30 7 using namespace std; 8 bool used[N]; 9 int head[N],t; 10 int que[N],d[N]; 11 int pre[N]; 12 struct node 13 { 14 int u,v,next,cost,flow; 15 }; 16 node e[M*4]; 17 void add(int u,int v,int f,int c) 18 { 19 e[t].u=u; 20 e[t].v=v; 21 e[t].flow=f; 22 e[t].cost=c; 23 e[t].next=head[u]; 24 head[u]=t++; 25 e[t].v=u; 26 e[t].u=v; 27 e[t].flow=0; 28 e[t].cost=-c; 29 e[t].next=head[v]; 30 head[v]=t++; 31 } 32 void init() 33 { 34 memset(head,-1,sizeof(head)); 35 t=0; 36 } 37 bool spfa(int num,int to) 38 { 39 int f,r,u,v,i,j; 40 memset(used,0,sizeof(used)); 41 memset(pre,-1,sizeof(pre)); 42 f=r=0; 43 for(i=0;i<=num;i++) 44 d[i]=inf; 45 used[0]=true; 46 que[r++]=0; 47 d[0]=0; 48 while(f!=r) 49 { 50 u=que[f++]; 51 used[u]=false; 52 for(i=head[u];i>=0;i=e[i].next) 53 { 54 v=e[i].v; 55 if(e[i].flow!=0&&d[v]>d[u]+e[i].cost) 56 { 57 pre[v]=i; 58 d[v]=d[u]+e[i].cost; 59 if(!used[v]) 60 { 61 used[v]=true; 62 que[r++]=v; 63 } 64 } 65 } 66 } 67 if(pre[to]==-1) 68 return false; 69 return true; 70 } 71 int solve(int num,int to) 72 { 73 int ans=0,minflow; 74 int i,j,v; 75 while(spfa(num,to)) 76 { 77 minflow=inf; 78 for(i=pre[to];i!=-1;i=pre[e[i].u]) 79 { 80 if(minflow>e[i].flow) 81 minflow=e[i].flow; 82 } 83 for(i=pre[to];i!=-1;i=pre[e[i].u]) 84 { 85 e[i].flow-=minflow; 86 e[i^1].flow+=minflow; 87 ans+=(minflow*e[i].cost); 88 } 89 } 90 return ans; 91 } 92 int main() 93 { 94 int n,m,i,j,u,v,c; 95 scanf("%d%d",&n,&m); 96 init(); 97 add(0,1,2,0); 98 add(n,n+1,2,0); 99 while(m--) 100 { 101 scanf("%d%d%d",&u,&v,&c); 102 add(u,v,1,c); 103 add(v,u,1,c); 104 } 105 printf("%d\n",solve(n+1,n+1)); 106 return 0; 107 }