【题解】Sigitseeing Tour
题目大意
有一张$n$个结点,$m$条混合边的图($1 \leq n \leq 200$,$1 \leq m \leq 1000$),求这张图是否存在欧拉回路。
题解
因为有混合边,所以我们要先给无向边随机定向,然后再调整方向。
随机定向之后,我们就得到一张有向图。
我们记录每个结点的入度$ind[i]$和出度$outd[i]$,根据欧拉路的性质可以得到,当$ind[i] + outd[i]$为奇数时,一定不存在欧拉路。
对于建边过程,因为原有的有向边不能变向,所以我们可以忽略,只需要将读入的无向边随机定向成有向边即,设容量为$1$即可(每条边只能走一次)。
对于每一个$ind[i] \leq outd[i]$的结点$i$,我们都从源点$s$向$i$连一条有向边,容量为$\frac{outd[i] - ind[i]}{2}$;对于$ind[i] > outd[i]$的结点$i$,从$i$向$t$连一条有向边,容量为$\frac{ind[i] - outd[i]}{2}$。这两种边的含义是连接结点$i$的边中,需要变向的边数。
显然,我们从$s$开始跑一次最大流,最后判断与$s$或$t$相连的边是否满流即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue> #define MAX_N (200 + 5)
#define MAX_M (1000 + 5) using namespace std; struct Edge
{
int to;
int weight;
int next;
}; int T;
int n, m;
int s, t;
int h[MAX_N], tot = ;
Edge e[MAX_N + MAX_M << ];
int ind[MAX_N], outd[MAX_N];
int dep[MAX_N];
int cur[MAX_N];
queue <int> q;
int maxflow; inline void AddEdge(int u, int v, int w)
{
e[++tot].to = v;
e[tot].weight = w;
e[tot].next = h[u];
h[u] = tot;
return;
}; bool BFS()
{
memset(dep, 0x7f, sizeof dep);
memcpy(cur, h, sizeof cur);
q.push(s);
dep[s] = ;
int u, v, w;
while(!q.empty())
{
u = q.front();
q.pop();
for(int i = h[u]; i; i = e[i].next)
{
v = e[i].to;
w = e[i].weight;
if(dep[v] > dep[u] + && w)
{
dep[v] = dep[u] + ;
q.push(v);
}
}
}
return dep[t] != 0x7f7f7f7f;
} int DFS(int u, int flow)
{
if(u == t)
{
maxflow += flow;
return flow;
}
int v, w;
int tmp, sum = ;
for(int i = cur[u]; i && flow; i = e[i].next)
{
cur[u] = i;
v = e[i].to;
w = e[i].weight;
if(dep[v] == dep[u] + && w && (tmp = DFS(v, min(flow, w))))
{
e[i].weight -= tmp;
e[i ^ ].weight += tmp;
sum += tmp;
flow -= tmp;
}
}
return sum;
} void Dinic()
{
while(BFS()) DFS(s, 0x7f7f7f7f);
return;
} int main()
{
scanf("%d", &T);
while(T--)
{
memset(h, , sizeof h);
memset(ind, , sizeof ind);
memset(outd, , sizeof outd);
tot = ;
maxflow = ;
scanf("%d%d", &n, &m);
s = ;
t = n + ;
int u, v, d;
for(int i = ; i <= m; ++i)
{
scanf("%d%d%d", &u, &v, &d);
++outd[u];
++ind[v];
if(!d)
{
AddEdge(u, v, );
AddEdge(v, u, );
}
}
bool isEuler = true;
for(int i = ; i <= n; ++i)
{
if(ind[i] + outd[i] & )
{
isEuler = false;
break;
}
}
if(!isEuler)
{
printf("impossible\n");
continue;
}
int tmp = tot;
for(int i = ; i <= n; ++i)
{
if(ind[i] <= outd[i])
{
AddEdge(s, i, outd[i] - ind[i] >> );
AddEdge(i, s, );
}
else
{
AddEdge(i, t, ind[i] - outd[i] >> );
AddEdge(t, i, );
}
}
Dinic();
for(int i = tmp + ; i <= tot; i += )
{
if(e[i].weight)
{
isEuler = false;
break;
}
}
if(!isEuler) printf("impossible\n");
else printf("possible\n");
}
return ;
}
参考程序
【题解】Sigitseeing Tour的更多相关文章
- World Tour Finals 2019 D - Distinct Boxes 题解
太神了,专门写一篇题解 qwq 简要题意:给你 \(R\) 个红球和 \(B\) 个蓝球,你要把它们放到 \(K\) 个箱子里,要求没有两个箱子完全相同(即两种球个数就相同),求 \(K\) 的最大值 ...
- POJ2135:Farm Tour——题解
http://poj.org/problem?id=2135 题目大意: 从1到n再回来,每条边只能走一次,问最短路. —————————————————— 如果不告诉我是费用流打死不会想这个…… 我 ...
- SPOJ1825/FTOUR2:Free tour II——包看得懂/看不懂题解
http://www.spoj.com/problems/FTOUR2/en/ 题目大意:给一棵黑白染色的树,求边权和最大且经过黑点不超过K的路径. ———————————————————— 前排膜拜 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- 【SPOJ】1825. Free tour II(点分治)
http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...
- 老oj2146 && Pku2135 Farm Tour
Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...
- 网络流(最大流) POJ 1637 Sightseeing tour
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8628 Accepted: 3636 ...
- 《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题
这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju/poj/uva的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就 ...
- 2013 CSU校队选拔赛(1) 部分题解
A: Decimal Time Limit: 1 Sec Memory Limit: 128 MB Submit: 99 Solved: 10 [ Submit][ Status][ Web ...
随机推荐
- 【记录】form-data与x-www-form-urlencoded的区别
1)application/x-www-form-urlencoded 这应该是最常见的 POST 提交数据的方式了.浏览器的原生 <form> 表单,如果不设置 enctype 属性,那 ...
- openstack stein部署手册 7. nova-compute
# 安装程序包 yum install -y openstack-nova-compute # 变更配置文件 cd /etc/nova mv nova.conf nova.conf.org cat & ...
- linux查看 inotify 提供的工具
[root@rsync-client-inotify ~]# ll /usr/local/bin/inotify* -rwxr-xr-x. 1 root root 38582 Jun 3 22:23 ...
- vue动态生成表单
vue动态生成表单 一.下拉框 <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...
- 字符串format函数使用
#format拼接字符串,format()内的参数必须为可迭代的对象p1="i am {2},age {1},{0}".format("seven",18,'a ...
- uwsgi配置cheaper模式进行自动弹性
[uwsgi] socket = 0.0.0.0:8080 protocol = http master = true hara-kiri = 60 chdir = /home/test/projec ...
- CF dp 题(1500-2000难度)
前言 从后往前刷 update 新增 \(\text{\color{red}{Mark}}\) 标记功能,有一定难度的题标记为 \(\text{\color{red}{红}}\) 色. 题单 (刷过的 ...
- mysql优化-覆盖索引查询,join
1 原始sql: SELECT a.* FROM event_data a WHERE a.receive_time >= '2018-03-28 00:00:00' AND a.receive ...
- django之csrf_exempt解决跨域请求的问题
一: from django.views.decorators.csrf import csrf_exempt # 获取微信返回的code信息 @csrf_exempt def wechat_auth ...
- Test 6.29 T1 预算方案
问题描述 "我需要你为我制订一个购物的方案.我将要为我的宫殿增置一些家具.有n 种备选家具,家具有主件和附件之分.在购买某个主件的附件之前,我必须先购买其对应的主件.某一主件的附件不会是另一 ...