TOJ 2099 Sightseeing tour(网络流判混合图欧拉回路)

描述

The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visited exactly once. The bus should also start and end at the same junction. As in any city, the streets are either one-way or two-way, traffic rules that must be obeyed by the tour bus. Help the executive board and determine if it‘s possible to construct a sightseeing tour under these constraints.

输入

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing two positive integers m and s, 1 <= m <= 200,1 <= s <= 1000 being the number of junctions and streets, respectively. The following s lines contain the streets. Each street is described with three integers, xi, yi, and di, 1 <= xi,yi <= m, 0 <= di <= 1, where xi and yi are the junctions connected by a street. If di=1, then the street is a one-way street (going from xi to yi), otherwise it‘s a two-way street. You may assume that there exists a junction from where all other junctions can be reached.

输出

For each scenario, output one line containing the text "possible" or "impossible", whether or not it‘s possible to construct a sightseeing tour.

样例输入

4
5 8
2 1 0
1 3 0
4 1 1
1 5 0
5 4 1
3 4 0
4 2 1
2 2 0
4 4
1 2 1
2 3 0
3 4 0
1 4 1
3 3
1 2 0
2 3 0
3 2 0
3 4
1 2 0
2 3 1
1 2 0
3 2 0

样例输出

possible
impossible
impossible
possible

题意

m个点,s条边,问是否存在欧拉回路

题解

网络流判混合路欧拉回路

关键是把图变成有向图再判断

容易知道如果是欧拉回路那么所有点的入度in,等于出度out

可以发现无向边(u,v),有向边(u,v)或是有向边(v,u),in[i]-out[i]的奇偶性不变

那我们就可以先假定无向边(u,v)变成有向边(u,v)

统计所有点的入出度

如果存在i,使得abs(in[i]-out[i])%2==1那么图不存在欧拉回路

对于in[i]>out[i]的点,说明i点需要多流出流量,建边(S,i)流量(in[i]-out[i])/2

对于in[i]<out[i]的点,说明i点需要多流入流量,建边(i,T)流量(out[i]-in[i])/2

对于所有无向边(u,v),建边(u,v)流量1

跑S->T的最大流,若满流即存在一种方法通过改变无向边的方向使得每个点的入度=出度(是不是类似于上下界可行流是否有解问题)

代码

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5
  6 const int maxn=1e5+5;
  7 const int maxm=2e5+5;
  8 const int INF=0x3f3f3f3f;
  9
 10 int TO[maxm],CAP[maxm],NEXT[maxm],tote;
 11 int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[400000];
 12 int n,m,S,T;
 13
 14 void add(int u,int v,int cap)
 15 {
 16     //printf("i=%d %d %d %d\n",tote,u,v,cap);
 17     TO[tote]=v;
 18     CAP[tote]=cap;
 19     NEXT[tote]=FIR[u];
 20     FIR[u]=tote++;
 21
 22     TO[tote]=u;
 23     CAP[tote]=0;
 24     NEXT[tote]=FIR[v];
 25     FIR[v]=tote++;
 26 }
 27 void bfs()
 28 {
 29     memset(gap,0,sizeof gap);
 30     memset(d,0,sizeof d);
 31     ++gap[d[T]=1];
 32     for(int i=1;i<=n;++i)cur[i]=FIR[i];
 33     int head=1,tail=1;
 34     q[1]=T;
 35     while(head<=tail)
 36     {
 37         int u=q[head++];
 38         for(int v=FIR[u];v!=-1;v=NEXT[v])
 39             if(!d[TO[v]])
 40                 ++gap[d[TO[v]]=d[u]+1],q[++tail]=TO[v];
 41     }
 42 }
 43 int dfs(int u,int fl)
 44 {
 45     if(u==T)return fl;
 46     int flow=0;
 47     for(int &v=cur[u];v!=-1;v=NEXT[v])
 48         if(CAP[v]&&d[u]==d[TO[v]]+1)
 49         {
 50             int Min=dfs(TO[v],min(fl,CAP[v]));
 51             flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^1]+=Min;
 52             if(!fl)return flow;
 53         }
 54     if(!(--gap[d[u]]))d[S]=n+1;
 55     ++gap[++d[u]],cur[u]=FIR[u];
 56     return flow;
 57 }
 58 int ISAP()
 59 {
 60     bfs();
 61     int ret=0;
 62     while(d[S]<=n)ret+=dfs(S,INF);
 63     return ret;
 64 }
 65 void init()
 66 {
 67     tote=0;
 68     memset(FIR,-1,sizeof FIR);
 69 }
 70 int main()
 71 {
 72     int N,u,v,op,s,_;
 73     scanf("%d",&_);
 74     while(_--)
 75     {
 76         int in[205]={0},out[205]={0};
 77         init();
 78         scanf("%d%d",&N,&m);
 79         S=N+1,T=S+1,n=T;
 80         for(int i=1;i<=m;i++)
 81         {
 82             scanf("%d%d%d",&u,&v,&op);
 83             in[v]++,out[u]++;
 84             if(op==0)
 85                 add(u,v,1);
 86         }
 87         int flag=1;
 88         for(int i=1;i<=N;i++)
 89             if((out[i]-in[i])%2==1)
 90             {
 91                 flag=0;
 92                 break;
 93             }
 94         if(!flag)
 95         {
 96             printf("impossible\n");
 97             continue;
 98         }
 99         int sum=0;
100         for(int i=1;i<=N;i++)
101         {
102             if(in[i]>out[i])
103             {
104                 sum+=(in[i]-out[i])/2;
105                 add(i,T,(in[i]-out[i])/2);
106             }
107             else if(out[i]>in[i])
108                 add(S,i,(out[i]-in[i])/2);
109         }
110         printf("%s\n",ISAP()==sum?"possible":"impossible");
111     }
112     return 0;
113 }

原文地址:https://www.cnblogs.com/taozi1115402474/p/9743778.html

时间: 2024-10-08 10:41:56

TOJ 2099 Sightseeing tour(网络流判混合图欧拉回路)的相关文章

POJ1637 Sightseeing tour(判定混合图欧拉回路)

有向连通图存在欧拉回路的充要条件是所有点入度=出度. 首先随便给定所有无向边一个方向(不妨直接是u->v方向),记录所有点的度(记:度=入度-出度). 这时如果有点的度不等于0,那么就不存在欧拉回路,就需要改变那些无向边的方向. 而改变一个无向边的方向,相当于边上两个端点的入度和出度都变化了1,它们的度±2. 另外,这样可以证明如果这时某个点的度为奇数那么一定不存在存在欧拉回路的解. 构图如下:所有无向边(u,v),建立容量为1的(u,v)边:所有度小于0的点u,建立容量为-deg/2的(vs,

混合图欧拉回路(hdoj3472 HS BDC)

欧拉回路基础知识戳这里 混合图:就是图里面有的边是有向边,有的边是无向边,组成的图叫做混合图. 要判混合图是否满足欧拉回路,首先必须满足欧拉图的条件 1:欧拉回路要求所有点的度数必须都为偶数,欧拉道路要求所有点的度数两个奇数. 2:给无向的边定向,首先任意定向,这些便之间网络流建边from到to容量为1,然后对于当前入度大于出度的点y,说明有d = (入度-出度)/2的边需要变成相反方向,我们这里不进行变向,而是用一个网络流的超级汇点T,给其建边y到T,容量为d. 然后对于当前出度大于入度的点x

POJ 1637 Sightseeing tour 混合图欧拉回路存在性判断

没有想到网络流还能解决这一类问题,完全想不到@[email protected] 一开始把所有的无向边制定任意方向有当做有向边看,然后统计每个点的入度和出度.以前有向图的欧拉回路判定是每个点的入读都等于出度,这样可以保证可以回到起点,现在在一些边可以调换方向的情况下,所有定点的入度和出度之差必定为偶数,因为调换任意一条边的方向都会使两个定点的入度和出度变化2,所以要构成一个欧拉回路所有点的入度和出度之差都为偶数,并设差为deg. 现在问题转化成了能否通过改变一些边的方向来是的所有点的入度出度都为

POJ 1637 Sightseeing tour (混合图欧拉回路)

POJ 1637 Sightseeing tour 链接:http://poj.org/problem?id=1637 题意:给定一个混合图,既有有向边,又有无向边,问是否存在欧拉回路. 思路: 1 定义 欧拉通路 (Euler tour)--通过图中每条边一次且仅一次,并且过每一顶点的通路. 欧拉回路 (Euler circuit)--通过图中每条边一次且仅一次,并且过每一顶点的回路. 欧拉图--存在欧拉回路的图. 2 无向图是否具有欧拉通路或回路的判定 G有欧拉通路的充分必要条件为:G 连通

POJ 1637 Sightseeing tour (混合图欧拉回路,网络最大流)

http://poj.org/problem?id=1637 Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7498   Accepted: 3123 Description The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can

POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

http://poj.org/problem?id=1637 题意:给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路. 思路: 构成有向图欧拉回路的要求是入度=出度,无向图的要求是所有顶点的度数为偶数. 但不管是那个,顶点的度数若是奇数,那都是不能构成的. 这道题目是非常典型的混合图欧拉回路问题,对于双向边,我们先随便定个向,然后就这样先记录好每个顶点的入度和出度. 如果有顶点的度数为奇数,可以直接得出结论,是不能构成欧拉回路的. 那么,如果都是偶数呢? 因为还会存在

poj1637 混合图欧拉回路的求解 网络流

题目链接: POJ1637 题意: 一幅图 ,给出有向边和无向边,问是否有经过所有边仅一次的欧拉回路 解题思路: 混合图欧拉回路的求解需要用到网络流,具体的建模方法如下: 1.先给所有无向边定向,然后统计所有点的入度和出度, 2.如果某点   入度-出度=奇数  那么一定不能构成欧拉回路   //入度+x  出度-x  度数差奇偶性不变 3.如果某点   出度>入度  建一条与源点连接的边  边容量为 (出度-入度)/2; 如果某点   出度<入度  建一条与汇点连接的边  边容量为 (入度-

hdu3472 HS BDC --- 混合图欧拉回路

讲的很好的资料: 点击打开链接 点击打开链接 #include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include &l

POJ 1637 混合图欧拉回路

先来复习一下混合图欧拉回路:给定一张含有单向边和双向边的图,使得每一点的入度出度相同. 首先对于有向边来说,它能贡献的入度出度是确定的,我们不予考虑.对于无向图,它可以通过改变方向来改变两端点的出入度.好的,我们不妨先将这些无向边随意定向,因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路,所以我们先扫一遍总度数看看是否为偶数,如果是奇数我们弃疗就好. 接下来我们要尝试着修复这些无向边的方向使得度数平衡.首先细化问题到每一个点:对于点u,如果它的入度大于出度,那