1.思路:题目要求求出两条路径,一条正向另一条反向,并且边不走重复,因此可以转换为费用流的模型,i至j有边(无向)拆成4条边,边的容量分别至1或0
因此可以保证每条边至多走一次。再建立源s,汇t,另w(s,1)=w(n-2,t)=2;w(,1,s)=w(t,n-2)=0;c(s,1)=c(1,s)=c(n-2,t)=c(t,n-2)=0;保证每只走出两条路!
2.代码
#include<cstdio> #include<iostream> #include<cstring> #include<string> using namespace std; #define N 1010 #define M 41000 #define INF 1000000000 struct Node{ int u,v,next; int w,c;//cost }; struct Graph{ Node E[M]; int first[N]; int _V,_E,src,dest; int que[N],front,rear; bool vis[N]; int cost[N],num[N],pre[N]; void init(int n){ _V=n+2,_E=0; src=0,dest=_V-1; memset(first,-1,4*_V);//!! } void build(int n,int m) { init(n); int u,v,w; for(int i=0; i<m; i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,1,w);add(v,u,1,w); } add(src,1,2,0);add(_V-2,dest,2,0); } void add(int u,int v,int c,int w){ E[_E].u=u,E[_E].v=v,E[_E].c=c,E[_E].w=w,E[_E].next=first[u],first[u]=_E,_E++; E[_E].u=v,E[_E].v=u,E[_E].c=0,E[_E].w=-w,E[_E].next=first[v],first[v]=_E,_E++;// } bool spfa(){ for(int i=0;i<_V;i++)cost[i]=INF,vis[i]=num[i]=false; cost[src]=0;pre[src]=-1; front=rear=0; que[rear++]=src; vis[src]=true;num[src]++; while(front!=rear){ int u=que[front++],v; vis[u]=false; if(front==N)front=0; for(int e=first[u];e!=-1;e=E[e].next){ v=E[e].v; if(E[e].c&&cost[v]>cost[u]+E[e].w){ cost[v]=cost[u]+E[e].w; pre[v]=e; if(!vis[v]){ que[rear++]=v; if(rear==N)rear=0; vis[v]=true;num[v]++; if(num[v]>_V)return false; } } } } return cost[dest]<INF; } int minCostMaxFlow(){ int minCost=0; while(spfa()){ int e,aug=INF;//!! for(e=pre[dest];e!=-1;e=pre[E[e].u])aug=aug<E[e].c?aug:E[e].c; for(e=pre[dest];e!=-1;e=pre[E[e].u])E[e].c-=aug,E[e^1].c+=aug; minCost+=cost[dest]*aug; } return minCost; } void display(){ for(int i=0; i<_V; i++){ for(int e=first[i]; e!=-1; e=E[e].next){ int u=E[e].u,v=E[e].v,c=E[e].c,w=E[e].w; cout<<u<<' '<<v<<' '<<c<<' '<<w<<endl; } } } } net; int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif int n,p; cin>>n>>p; net.build(n,p); // net.display(); cout<<net.minCostMaxFlow()<<endl; return 0; } //
大家把其中的
if(rear==N)rear=0;
改成
if(rear==N)front=0;
用C++提交试试会有神奇的事情发生!