zoj 1992 || poj 1637 Sightseeing Tour
2011-03-07 22:02
423 查看
混合图的欧拉回路。
以前没遇到过这种题,纠结啊。。。搜了下,发现是需要用最大流解的,隐约记得黑书上最大流有讲这个的,就去翻黑书了。
黑书提供了两种算法,第一种自己模拟了下,觉得有点看不懂,觉得它书有的地方没说清楚,而且我自己模拟的结果不对 = =。。。
第二种算法是网上大家经常用的,理解了下。
大致就是,先将无向边定向,就是比如1<->3,可以定它的方向为1->3,1的出度++,3的入度++即可。
读入的时候如果遇到无向边,把这条边加入待建的网络中,流量为1。读入完后,然后用出度减入度得到x,如果x为奇数,肯定不存在欧拉回路,如果没有奇数,就用最大流求解。
如果x大于0,则建一条s(源点)到当前点容量为x/2的边,如果x小于0,建一条从当前点到 t(汇点)容量为|x/2|的边。
然后求最大流,如果是满流(即s出的流==t入的流即可,s指的是建图的时候连接s的边的容量和)就满足欧拉回路。
这题我用递归的dinic做的,开始用并查集判连通了,嘻嘻,好不容易把邻接矩阵改成邻接表了,嘻嘻,我好伟大~~拉拉~~~
这题在zoj排第一了,哇咔咔咔~~~
以前没遇到过这种题,纠结啊。。。搜了下,发现是需要用最大流解的,隐约记得黑书上最大流有讲这个的,就去翻黑书了。
黑书提供了两种算法,第一种自己模拟了下,觉得有点看不懂,觉得它书有的地方没说清楚,而且我自己模拟的结果不对 = =。。。
第二种算法是网上大家经常用的,理解了下。
大致就是,先将无向边定向,就是比如1<->3,可以定它的方向为1->3,1的出度++,3的入度++即可。
读入的时候如果遇到无向边,把这条边加入待建的网络中,流量为1。读入完后,然后用出度减入度得到x,如果x为奇数,肯定不存在欧拉回路,如果没有奇数,就用最大流求解。
如果x大于0,则建一条s(源点)到当前点容量为x/2的边,如果x小于0,建一条从当前点到 t(汇点)容量为|x/2|的边。
然后求最大流,如果是满流(即s出的流==t入的流即可,s指的是建图的时候连接s的边的容量和)就满足欧拉回路。
这题我用递归的dinic做的,开始用并查集判连通了,嘻嘻,好不容易把邻接矩阵改成邻接表了,嘻嘻,我好伟大~~拉拉~~~
这题在zoj排第一了,哇咔咔咔~~~
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 205 using namespace std; int pre[MAX],n; int ind[MAX],outd[MAX]; int lev[MAX]; typedef struct MAP{ int cap,to; int next; }MAP; MAP node[3000]; int head[MAX]; int cou; void init() { cou = 2; memset(node,'/0',sizeof(node)); memset(head,-1,sizeof(head)); memset(ind,0,sizeof(ind)); memset(outd,0,sizeof(outd)); for(int i=1; i<=n; i++) pre[i] = i; } int find(int x) { while( x != pre[x] ) x = pre[x]; return x; } void Union(int x,int y) { int a = find(x); int b = find(y); if( a == b ) return ; int p = min(a,b); pre[a] = pre[b] = pre[x] = pre[y] = p; } int check() { for(int i=1; i<=n; i++) if( find(i) != 1 ) return 0; return 1; } void Add(int u,int v,int cap) { node[cou].to = v; node[cou].cap = cap; node[cou].next = head[u]; head[u] = cou++; node[cou].to = u; node[cou].cap = 0; node[cou].next = head[v]; head[v] = cou++; } queue<int> q; int BFS(int s,int t) { int p,u,v,cap; memset(lev,-1,sizeof(lev)); q.push(s); lev[s] = 0; while( !q.empty() ) { u = q.front(); q.pop(); p = head[u]; while( p != -1 ) { v = node[p].to; cap = node[p].cap; if( cap > 0 && lev[v] == -1 ) { lev[v] = lev[u] + 1; q.push(v); } p = node[p].next; } } return lev[t] != -1; } int Dinic(int k,int sum,int s,int t) { int i,a,os; if( k == t ) return sum; os = sum; int p = head[k]; while( p != -1 && sum ) { int to = node[p].to; int cap = node[p].cap; if( lev[to] == lev[k] + 1 && cap > 0 ) { a = Dinic(to,min(sum,cap),s,t); node[p^1].cap += a; node[p].cap -= a; sum -= a; } p = node[p].next; } return os - sum; } int main() { int m,from,to,s; int ncases; scanf("%d",&ncases); while( ncases-- ) { scanf("%d%d",&n,&m); init(); while( m-- ) { scanf("%d%d%d",&from,&to,&s); if( from == to ) continue; ind[to]++; outd[from]++; Union(from,to); if( s != 1 ) Add(from,to,1); } if( !check() ) { printf("impossible/n"); continue; } int flag = 1; int sum = 0; for(int i=1; i<=n; i++) { outd[i] -= ind[i]; if( outd[i] % 2 == 1 ) { flag = 0; break; } outd[i] /= 2; if( outd[i] > 0 ) { Add(0,i,outd[i]); sum += outd[i]; } else Add(i,n+1,-outd[i]); } if( !flag ) { printf("impossible/n"); continue; } int ans = 0; while( BFS(0,n+1) ) ans += Dinic(0,INT_MAX,0,n+1); if( ans == sum ) printf("possible/n"); else printf("impossible/n"); } return 0; }
相关文章推荐
- 【POJ】【1637】Sightseeing tour
- Poj 1637 Sightseeing tour (混合图的欧拉回路判定)
- poj 1637 Sightseeing tour 混合图的欧拉回路
- POJ 1637 Sightseeing tour(最大流)
- POJ 1637 - Sightseeing tour
- POJ 1637:Sightseeing tour 混合图欧拉回路
- POJ 1637 Sightseeing tour (混合图欧拉回路)
- poj--1637--Sightseeing tour(网络流,最大流判断混合图是否存在欧拉图)
- poj 1637 Sightseeing tour
- POJ - 1637 Sightseeing tour (混合图欧拉路径欧拉图判断)
- POJ-1637 Sightseeing tour(通过网络流判定混合图的欧拉回路)
- POJ-1637 Sightseeing tour
- poj 1637 Sightseeing tour
- POJ 1637 -- Sightseeing tour
- POJ 1637 Sightseeing tour 混合欧拉回路
- POJ 1637 Sightseeing tour(混合图的欧拉回路)
- poj--1637--Sightseeing tour(网络流,最大流判断混合图是否存在欧拉图)
- POJ 1637 Sightseeing tour 混合图欧拉回路 最大流
- POJ1637 Sightseeing tour 网络流
- POJ 1637 Sightseeing Tour