Language: Default Sightseeing tour
Description 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 Input 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, Output For each scenario, output one line containing the text "possible" or "impossible", whether or not it‘s possible to construct a sightseeing tour. Sample Input 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 Sample Output possible impossible impossible possible Source |
题意:求混合图是否有欧拉回路。
思路:首先是基图联通(不考虑度为0的点),然后需要借助网络流来判断。
首先给原图中的无向边随便指定一个方向(初始定向),将原图改为有向图G’,然后的任务就是改变G‘中某些边得方向(当然是无向边转化来的,原 有向边不变)使其满足每个点的入度等于出度。
设d[i]为G‘中(点i的出度-点i的入度)。可知,在改变G‘中边的方向时,任何点的d值的奇偶性都不会变(设将边<i,j>改为<j,i>,则i的入度加1出度减1,j的入度减1出度加1,两者之差加2或减2,奇偶性不变)!而最终要求的是每个点的入度等于出度,即每个点的d值为0,是偶数;故:若初始定向得到的G‘中任意一个点的d值是奇数,那么原图中一定不存在欧拉环!
若初始d值都是偶数,则将G‘改成网络:添加源点S和汇点T,对于每个d[i]>0的点i,连边<S,i>,容量为d[i]/2;对于每个d[i]<0的点j,连边<j,T>,容量为-d[j]/2;G‘中的每条无向边在网络中仍保留,容量为1(表示该边最多只能被改变方向一次)。求这个网络的最大流,若S引出的所有边均满流,则原图是欧拉图,否则不是欧拉图。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define maxn 1005 #define MAXN 222 #define mod 1000000009 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FRL(i,a,b) for(i = a; i < b; i++) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") const int MAXM = 3000; typedef long long ll; using namespace std; struct Edge { int to,next,cap,flow; }edge[MAXM]; int st,ed; int d[MAXN]; int tol,m,s; int head[MAXN]; int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; void init() { tol=0; memset(head,-1,sizeof(head)); } //加边,单向图三个参数,双向图四个参数 void addedge(int u,int v,int w,int rw=0) { edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u]; edge[tol].flow=0; head[u]=tol++; edge[tol].to=u; edge[tol].cap=rw; edge[tol].next=head[v]; edge[tol].flow=0; head[v]=tol++; } //输入参数:起点,终点,点的总数 //点的编号没有影响,只要输入点的总数 int sap(int start,int end,int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; int ans=0; while (dep[start]<N) { if (u==end) { int Min=INF; for (int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if (Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for (int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u=start; ans+=Min; continue; } bool flag=false; int v; for (int i=cur[u];i!=-1;i=edge[i].next) { v=edge[i].to; if (edge[i].cap-edge[i].flow && dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if (flag) { u=v; continue; } int Min=N; for (int i=head[u];i!=-1;i=edge[i].next) if (edge[i].cap-edge[i].flow && dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if (!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if (u!=start) u=edge[pre[u]^1].to; } return ans; } int main() { int i,j,cas,u,v,w; sf(cas); while (cas--) { sff(m,s); st=0;ed=m+1; init(); mem(d,0); FRE(i,1,s) { sfff(u,v,w); d[u]++; d[v]--; if (w!=1) addedge(u,v,1); } bool flag=true; int outflow=0; FRE(i,1,m) { if (abs(d[i])%2==1) { flag=false; break; } if (d[i]>0) { addedge(st,i,d[i]/2); outflow+=d[i]/2; } if (d[i]<0) addedge(i,ed,abs(d[i])/2); } if (!flag) { printf("impossible\n"); continue; } int Maxflow=sap(st,ed,m+2); if (Maxflow==outflow) printf("possible\n"); else printf("impossible\n"); } return 0; } /* 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 */