UVa 10806 & 费用流+意识流...

题意:

  一张无向图,求两条没有重复的从S到T的路径.

SOL:

  网络流为什么屌呢..因为网络流的容量,流量,费用能对许许多多的问题进行相应的转化,然后它就非常的屌.

  对于这道题呢,不是要没有重复吗?不是一条边只能走一次吗?那么容量上界就是1.不是要有两条吗?那么总流量就是2.不是带权吗?那么加个费用.

  

  WA得惨不忍睹,最后发现边从0开始记异或以后会改变一些非常奇异的边...真是丝帛= =

Code

  

/*==========================================================================
# Last modified: 2016-03-07 14:07
# Filename: uva10806.cpp
# Description: 
==========================================================================*/
#define me AcrossTheSky 
#include <cstdio> 
#include <cmath> 
#include <ctime> 
#include <string> 
#include <cstring> 
#include <cstdlib> 
#include <iostream> 
#include <algorithm> 
  
#include <set> 
#include <map> 
#include <stack> 
#include <queue> 
#include <vector> 
 
#define lowbit(x) (x)&(-x) 
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
#define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
#define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
#define ls(a,b) (((a)+(b)) << 1) 
#define rs(a,b) (((a)+(b)) >> 1) 
#define getlc(a) ch[(a)][0] 
#define getrc(a) ch[(a)][1] 
 
#define maxn 1000 
#define maxm 100000 
#define pi 3.1415926535898 
#define _e 2.718281828459 
#define INF 1070000000 
using namespace std; 
typedef long long ll; 
typedef unsigned long long ull; 
 
template<class T> inline 
void read(T& num) { 
    bool start=false,neg=false; 
    char c; 
    num=0; 
    while((c=getchar())!=EOF) { 
        if(c=='-') start=neg=true; 
        else if(c>='0' && c<='9') { 
            start=true; 
            num=num*10+c-'0'; 
        } else if(start) break; 
    } 
    if(neg) num=-num; 
} 
/*==================split line==================*/ 
struct Edge{
	int from,to,w,c;
}e[maxm];
int sume,flow,ans,n,m;
int d[maxn],first[maxn],next[maxm],from[maxn];
bool inq[maxn];

void addedge(int x,int y,int cap,int cost){
	sume++; e[sume].from=x; e[sume].to=y; e[sume].w=cap; e[sume].c=cost;
	next[sume]=first[x]; first[x]=sume;
	sume++; e[sume].from=y; e[sume].to=x; e[sume].w=0; e[sume].c=-cost;
	next[sume]=first[y]; first[y]=sume;
}
bool spfa(){
	queue<int> q;
	FORP(i,0,n) d[i]=INF;
	memset(inq,false,sizeof(inq));
	memset(from,0,sizeof(from));
	q.push(0); d[0]=0; inq[0]=true;
	while(!q.empty()){
		int now=q.front(); q.pop(); inq[now]=false;
		for(int i=first[now];i!=-1;i=next[i])
		if (e[i].w && d[now]+e[i].c<d[e[i].to]) {
			d[e[i].to]=d[now]+e[i].c;
			from[e[i].to]=i;
			//q.push(e[i].to); 
			if (!inq[e[i].to]){
				inq[e[i].to]=true;
				q.push(e[i].to);
			}
		}
	}
	if (d[n]==INF) return false;
	return true;
}
void mincost(){
	int x=INF,i=from[n];
	while (i) {
		x=min(e[i].w,x); i=from[e[i].from];
	}
	flow+=x;
	i=from[n];
	while (i){
		e[i].w-=x;
		e[i^1].w+=x;
		//ans+=(x*e[i].c);
		i=from[e[i].from];
	}
	ans+=d[n]*x;
}
void reset(){
	sume=1; flow=0; ans=0;
	memset(e,0,sizeof(e));
	FORP(i,0,maxn) first[i]=-1;
	memset(next,0,sizeof(next));
}
int main(){
	while (scanf("%d",&n)!=EOF){
		reset();
		 if (n==0) return 0;
		 read(m);
		 FORP(i,1,m) {
		 	int x,y,w; read(x); read(y); read(w);
			addedge(x,y,1,w);
			addedge(y,x,1,w);
		 }
		 addedge(0,1,2,0);
		 addedge(n,n+1,2,0);
		 n++;
		 while (spfa()) mincost();
		 if (flow<2) printf("Back to jail\n");
		 else printf("%d\n",ans);
	}
}

 

posted @ 2016-03-07 15:49  YCuangWhen  阅读(182)  评论(0编辑  收藏  举报