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++提交试试会有神奇的事情发生!