题目大意

  有一张$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的更多相关文章

  1. World Tour Finals 2019 D - Distinct Boxes 题解

    太神了,专门写一篇题解 qwq 简要题意:给你 \(R\) 个红球和 \(B\) 个蓝球,你要把它们放到 \(K\) 个箱子里,要求没有两个箱子完全相同(即两种球个数就相同),求 \(K\) 的最大值 ...

  2. POJ2135:Farm Tour——题解

    http://poj.org/problem?id=2135 题目大意: 从1到n再回来,每条边只能走一次,问最短路. —————————————————— 如果不告诉我是费用流打死不会想这个…… 我 ...

  3. SPOJ1825/FTOUR2:Free tour II——包看得懂/看不懂题解

    http://www.spoj.com/problems/FTOUR2/en/ 题目大意:给一棵黑白染色的树,求边权和最大且经过黑点不超过K的路径. ———————————————————— 前排膜拜 ...

  4. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  5. 【SPOJ】1825. Free tour II(点分治)

    http://www.spoj.com/problems/FTOUR2/ 先前看了一会题解就自己yy出来了...对拍过后交tle.................. 自己造了下大数据........t ...

  6. 老oj2146 && Pku2135 Farm Tour

    Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...

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

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

  8. 《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题

    这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju/poj/uva的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就 ...

  9. 2013 CSU校队选拔赛(1) 部分题解

    A: Decimal Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 99   Solved: 10 [ Submit][ Status][ Web ...

随机推荐

  1. 【记录】form-data与x-www-form-urlencoded的区别

    1)application/x-www-form-urlencoded 这应该是最常见的 POST 提交数据的方式了.浏览器的原生 <form> 表单,如果不设置 enctype 属性,那 ...

  2. openstack stein部署手册 7. nova-compute

    # 安装程序包 yum install -y openstack-nova-compute # 变更配置文件 cd /etc/nova mv nova.conf nova.conf.org cat & ...

  3. linux查看 inotify 提供的工具

    [root@rsync-client-inotify ~]# ll /usr/local/bin/inotify* -rwxr-xr-x. 1 root root 38582 Jun 3 22:23 ...

  4. vue动态生成表单

    vue动态生成表单 一.下拉框 <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...

  5. 字符串format函数使用

    #format拼接字符串,format()内的参数必须为可迭代的对象p1="i am {2},age {1},{0}".format("seven",18,'a ...

  6. uwsgi配置cheaper模式进行自动弹性

    [uwsgi] socket = 0.0.0.0:8080 protocol = http master = true hara-kiri = 60 chdir = /home/test/projec ...

  7. CF dp 题(1500-2000难度)

    前言 从后往前刷 update 新增 \(\text{\color{red}{Mark}}\) 标记功能,有一定难度的题标记为 \(\text{\color{red}{红}}\) 色. 题单 (刷过的 ...

  8. mysql优化-覆盖索引查询,join

    1 原始sql: SELECT a.* FROM event_data a WHERE a.receive_time >= '2018-03-28 00:00:00' AND a.receive ...

  9. django之csrf_exempt解决跨域请求的问题

    一: from django.views.decorators.csrf import csrf_exempt # 获取微信返回的code信息 @csrf_exempt def wechat_auth ...

  10. Test 6.29 T1 预算方案

    问题描述 "我需要你为我制订一个购物的方案.我将要为我的宫殿增置一些家具.有n 种备选家具,家具有主件和附件之分.在购买某个主件的附件之前,我必须先购买其对应的主件.某一主件的附件不会是另一 ...