Sightseeing tour
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6448   Accepted: 2654

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 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.

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, 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.

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

给出一张混合图(有有向边,也有无向边),判断是否存在欧拉回路。

首先是对图中的无向边随意定一个方向,然后统计每个点的入度(indeg)和出度(outdeg),如果(indeg - outdeg)是奇数的话,一定不存在欧拉回路;

如果所有点的入度和出度之差都是偶数,那么就开始网络流构图:

1,对于有向边,舍弃;对于无向边,就按照最开始指定的方向建权值为 1 的边;

2,对于入度小于出度的点,从源点连一条到它的边,权值为(outdeg - indeg)/2;出度小于入度的点,连一条它到汇点的权值为(indeg - outdeg)/2 的边;

构图完成,如果满流(求出的最大流值 == 和汇点所有连边的权值之和),那么存在欧拉回路,否则不存在。

另附一个讲解欧拉图不错的博客:http://www.cnblogs.com/destinydesigner/archive/2009/09/28/1575674.html

SAP果然快,0ms:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int VM=;
const int EM=;
const int INF=0x3f3f3f3f; struct Edge{
int to,nxt;
int cap;
}edge[EM<<]; int n,m,cnt,head[VM];
int src,des,tot,sum,indeg[VM],outdeg[VM];
int dep[VM],gap[VM],cur[VM],aug[VM],pre[VM]; void addedge(int cu,int cv,int cw){
edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu];
head[cu]=cnt++;
edge[cnt].to=cu; edge[cnt].cap=; edge[cnt].nxt=head[cv];
head[cv]=cnt++;
} int SAP(int n){
int max_flow=,u=src,v;
int id,mindep;
aug[src]=INF;
pre[src]=-;
memset(dep,,sizeof(dep));
memset(gap,,sizeof(gap));
gap[]=n;
for(int i=;i<=n;i++)
cur[i]=head[i]; // 初始化当前弧为第一条弧
while(dep[src]<n){
int flag=;
if(u==des){
max_flow+=aug[des];
for(v=pre[des];v!=-;v=pre[v]){ // 路径回溯更新残留网络
id=cur[v];
edge[id].cap-=aug[des];
edge[id^].cap+=aug[des];
aug[v]-=aug[des]; // 修改可增广量,以后会用到
if(edge[id].cap==) // 不回退到源点,仅回退到容量为0的弧的弧尾
u=v;
}
}
for(int i=cur[u];i!=-;i=edge[i].nxt){
v=edge[i].to; // 从当前弧开始查找允许弧
if(edge[i].cap> && dep[u]==dep[v]+){ // 找到允许弧
flag=;
pre[v]=u;
cur[u]=i;
aug[v]=min(aug[u],edge[i].cap);
u=v;
break;
}
}
if(!flag){
if(--gap[dep[u]]==) /* gap优化,层次树出现断层则结束算法 */
break;
mindep=n;
cur[u]=head[u];
for(int i=head[u];i!=-;i=edge[i].nxt){
v=edge[i].to;
if(edge[i].cap> && dep[v]<mindep){
mindep=dep[v];
cur[u]=i; // 修改标号的同时修改当前弧
}
}
dep[u]=mindep+;
gap[dep[u]]++;
if(u!=src) // 回溯继续寻找允许弧
u=pre[u];
}
}
return max_flow;
} void Init(){
cnt=;
memset(head,-,sizeof(head));
memset(indeg,,sizeof(indeg));
memset(outdeg,,sizeof(outdeg));
} int main(){ //freopen("input.txt","r",stdin); int t;
scanf("%d",&t);
while(t--){
Init();
scanf("%d%d",&n,&m);
int u,v,c;
for(int i=;i<m;i++){
scanf("%d%d%d",&u,&v,&c);
indeg[v]++;
outdeg[u]++;
if(c==)
addedge(u,v,);
} int flag=;
for(int i=;i<=n;i++)
if((indeg[i]-outdeg[i])%==){
flag=;
break;
}
if(!flag)
puts("impossible");
else{
sum=;
src=, des=n+;
for(int i=;i<=n;i++){ //无向边建图,有向边舍弃
if(indeg[i]<outdeg[i])
addedge(src,i,(outdeg[i]-indeg[i])/);
else if(indeg[i]>outdeg[i]){
addedge(i,des,(indeg[i]-outdeg[i])/);
sum+=(indeg[i]-outdeg[i])/;
}
}
int ans=SAP(des+);
if(sum==ans)
puts("possible");
else
puts("impossible");
}
}
return ;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int VM=;
const int EM=;
const int INF=0x3f3f3f3f; struct Edge{
int u,v,nxt;
int cap;
}edge[EM<<]; int n,m,cnt,head[VM];
int src,des,tot,sum,dep[VM],indeg[VM],outdeg[VM]; void addedge(int cu,int cv,int cw){
edge[cnt].u=cu; edge[cnt].v=cv; edge[cnt].cap=cw;
edge[cnt].nxt=head[cu]; head[cu]=cnt++;
edge[cnt].u=cv; edge[cnt].v=cu; edge[cnt].cap=;
edge[cnt].nxt=head[cv]; head[cv]=cnt++;
} void Init(){
cnt=;
memset(head,-,sizeof(head));
memset(indeg,,sizeof(indeg));
memset(outdeg,,sizeof(outdeg));
} int BFS(){
queue<int> q;
while(!q.empty())
q.pop();
memset(dep,-,sizeof(dep));
dep[src]=;
q.push(src);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].v;
if(edge[i].cap> && dep[v]==-){ //没有标记,且可行流大于0
dep[v]=dep[u]+;
q.push(v);
}
}
}
return dep[des]!=-; //汇点是否成功标号,也就是说是否找到增广路
} int DFS(int u,int minx){
if(u==des)
return minx;
int tmp;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].v;
if(edge[i].cap> && dep[v]==dep[u]+ && (tmp=DFS(v,min(minx,edge[i].cap)))){
edge[i].cap-=tmp;
edge[i^].cap+=tmp;
return tmp;
}
}
dep[u]=-;
return ;
} int Dinic(){
int ans=,tmp;
while(BFS()){
while(){
tmp=DFS(src,INF);
if(tmp==)
break;
ans+=tmp;
}
}
return ans;
} int main(){ //freopen("input.txt","r",stdin); int t;
scanf("%d",&t);
while(t--){
Init();
scanf("%d%d",&n,&m);
int u,v,c;
for(int i=;i<m;i++){
scanf("%d%d%d",&u,&v,&c);
indeg[v]++;
outdeg[u]++;
if(c==)
addedge(u,v,);
} int flag=;
for(int i=;i<=n;i++)
if((indeg[i]-outdeg[i])%==){
flag=;
break;
}
if(!flag)
puts("impossible");
else{
sum=;
src=, des=n+;
for(int i=;i<=n;i++){ //无向边建图,有向边舍弃
if(indeg[i]<outdeg[i])
addedge(src,i,(outdeg[i]-indeg[i])/);
else if(indeg[i]>outdeg[i]){
addedge(i,des,(indeg[i]-outdeg[i])/);
sum+=(indeg[i]-outdeg[i])/;
}
}
int ans=Dinic();
if(sum==ans)
puts("possible");
else
puts("impossible");
}
}
return ;
}

POJ 1637 Sightseeing tour (SAP | Dinic 混合欧拉图的判断)的更多相关文章

  1. POJ 1637 Sightseeing tour(最大流)

    POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...

  2. POJ 1637 Sightseeing tour (混合图欧拉路判定)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6986   Accepted: 2901 ...

  3. POJ 1637 - Sightseeing tour - [最大流解决混合图欧拉回路]

    嗯,这是我上一篇文章说的那本宝典的第二题,我只想说,真TM是本宝典……做的我又痛苦又激动……(我感觉ACM的日常尽在这张表情中了) 题目链接:http://poj.org/problem?id=163 ...

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

    Sightseeing tour   Description The city executive board in Lund wants to construct a sightseeing tou ...

  5. POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9276   Accepted: 3924 ...

  6. 网络流(最大流) POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8628   Accepted: 3636 ...

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

    http://poj.org/problem?id=1637 题意:给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路. 思路: 构成有向图欧拉回路的要求是入度=出度,无向图 ...

  8. POJ 1637 Sightseeing tour ★混合图欧拉回路

    [题目大意]混合图欧拉回路(1 <= N <= 200, 1 <= M <= 1000) [建模方法] 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为 ...

  9. poj 1637 Sightseeing tour 混合图欧拉回路 最大流 建图

    题目链接 题意 给定一个混合图,里面既有有向边也有无向边.问该图中是否存在一条路径,经过每条边恰好一次. 思路 从欧拉回路说起 首先回顾有向图欧拉回路的充要条件:\(\forall v\in G, d ...

随机推荐

  1. Java——DOM方式生成XML (转)

    http://blog.csdn.net/u012325167/article/details/50943202 使用DOM方式生成XML文件有如下几步: 首先是创建DOM树(即规定XML文件中的内容 ...

  2. glGetString(GL_VERSION) returns “OpenGL ES-CM 1.1” but my phone supports OpenGL 2

      [问] I'm trying to make an NDK based OpenGL application. At some point in my code, I want to check ...

  3. java语言特性之一

    package java.util.Collections; public static int indexOfSubList(List<?> source, List<?> ...

  4. Awk使用及站点日志分析

    Awk使用及站点日志分析 Awk简单介绍 概述 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入, ...

  5. 微软BI 之SSRS 系列 - 如何实现报表标签的本地化 - 中文和英文的互换

    SSRS 中并没有直接提供本地化的配置方式,因此在 SSRS 中实现本地化,比如有英文标题还有可选的中文标题,就需要通过其它的方式来解决. 比如默认是这样的英文标题 - 但是本地中方用户可能比较喜欢看 ...

  6. Go语言中Path包用法

    // path package main import ( "fmt" "os" "path" "path/filepath&qu ...

  7. websocket与canvas[转]

    server端还是用tomcat7的方式客户端 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  ...

  8. SpringMVC的页面几种返回方式

    package com.boventech.learning.controller; import java.util.HashMap; import java.util.Map; import or ...

  9. iPad Air 2全然评測:可怕的三核CPU、六核GPU

    在了解了三核心A8X的基本情况后.我们再来通过測试数据,全面地了解一下iPad Air 2的性能表现,包含CPU.GPU.存储.电池.屏幕.摄像头.导航等等. [CPU性能測试:三核太可怕了] 移动处 ...

  10. Webwork【07】文件上传下载

    Web上传和下载应该是很普遍的一个需求,无论是小型网站还是大并发访问的交易网站.WebWork 当然也提供了很友好的拦截器来实现对文件的上传,让我们可以专注与业务逻辑的设计和实现,在实现上传和下载时顺 ...