B - Sightseeing tour POJ - 1637

https://blog.csdn.net/qq_36551189/article/details/80905345

首先要了解一下欧拉回路的基本思路。

欧拉回路:如果是无向图,那么每一个点连的边的数量为偶数,如果是有向图,那么每一个点的入度要等于出度。

欧拉路径:这个欧拉路径是没有成环的,如果是无向图,那么除了两个点连的边是奇数,其他都是偶数,

如果是有向图,那么除了有一个点入度比出度大1,有一个点的出度比入度大1 ,其他都是入度等于出度。

这个题目的基本思路就涉及到了欧拉回路。

这个地方难处理的就是有无向和有向边的混合,这个无向很难处理,但是这个无向最后都要转化成有向。

根据欧拉回路的一些基本性质我们可以知道,有向图每一个点的入度要等于出度。

所以我们可以先给无向图随意定一个方向然后我们用 d=出度-入度 因为我们随意改变一条边的方向这个d的变化量为2

所以就说明之后改变边的方向并不会改变改变这个d的奇偶性。

根据欧拉回路我们就可以知道我们需要的是这个d==0

这个时候就需要用到最大流,怎么用最大流解决这个问题呢,

就是把d大于0的部分和源点相连,因为d大于0如果是欧拉回路那么就肯定是由其他边d小于0,

其他边d<0说明出度小于入度,也就是说有点的入度会小于出度,就是说在任意给定边的时候有点把边连到了这个d<0的点上面,

说到这里其实这个图就建的差不多了。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
struct edge {
int u, v, c, f;
edge(int u, int v, int c, int f) :u(u), v(v), c(c), f(f) {}
};
vector<edge>e;
vector<int>G[maxn];
int level[maxn];//BFS分层,表示每个点的层数
int iter[maxn];//当前弧优化
int m;
void init(int n) {
for (int i = ; i <= n; i++)G[i].clear();
e.clear();
}
void addedge(int u, int v, int c) {
e.push_back(edge(u, v, c, ));
e.push_back(edge(v, u, , ));
m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
void BFS(int s)//预处理出level数组
//直接BFS到每个点
{
memset(level, -, sizeof(level));
queue<int>q;
level[s] = ;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v = ; v < G[u].size(); v++) {
edge& now = e[G[u][v]];
if (now.c > now.f && level[now.v] < ) {
level[now.v] = level[u] + ;
q.push(now.v);
}
}
}
}
int dfs(int u, int t, int f)//DFS寻找增广路
{
if (u == t)return f;//已经到达源点,返回流量f
for (int &v = iter[u]; v < G[u].size(); v++)
//这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历
//在每次找增广路的时候,数组要清空
{
edge &now = e[G[u][v]];
if (now.c - now.f > && level[u] < level[now.v])
//now.c - now.f > 0表示这条路还未满
//level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想
{
int d = dfs(now.v, t, min(f, now.c - now.f));
if (d > ) {
now.f += d;//正向边流量加d
e[G[u][v] ^ ].f -= d;
//反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到
return d;
}
}
}
return ;
}
int Maxflow(int s, int t) {
int flow = ;
for (;;) {
BFS(s);
if (level[t] < )return flow;//残余网络中到达不了t,增广路不存在
memset(iter, , sizeof(iter));//清空当前弧数组
int f;//记录增广路的可增加的流量
while ((f = dfs(s, t, INF)) > ) {
flow += f;
}
}
return flow;
}
int in[maxn], out[maxn]; int main()
{
int k;
scanf("%d", &k);
while(k--)
{
int n, m;
scanf("%d%d", &n, &m);
init(n + m);
memset(in, , sizeof(in));
memset(out, , sizeof(out));
int s = , t = n + ;
for(int i=;i<=m;i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
out[u]++; in[v]++;
if (w == ) addedge(u, v, );
}
bool flag = false;
for(int i=;i<=n;i++)
{
if ((out[i] - in[i]) & ) flag = true;
else if (out[i] > in[i]) addedge(s, i, (out[i] - in[i]) / );
else if (in[i] > out[i]) addedge(i, t, (in[i] - out[i]) / );
}
if (flag) {
printf("impossible\n");
continue;
}
int ans = Maxflow(s, t);
for(int i=;i<G[].size();i++)
{
edge now = e[G[][i]];
if (now.c != now.f) flag = true;
}
if (flag) printf("impossible\n");
else printf("possible\n");
}
return ;
}

欧拉回路

网络流 + 欧拉回路 = B - Sightseeing tour POJ - 1637的更多相关文章

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

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

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

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

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

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

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

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

  5. POJ 1637 Sightseeing tour(最大流)

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

  6. POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)

                                                                Sightseeing tour Time Limit: 1000MS   Me ...

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

    描述 The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that to ...

  8. POJ 1637 Sightseeing tour (SAP | Dinic 混合欧拉图的判断)

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

  9. POJ 1637 Sightseeing tour

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

随机推荐

  1. Git中rebase失败了如何进行恢复

    rebase失败后的恢复 记一次翻车现场 记一次翻车的现场,很早之前提的PR后面由于需求的变便去忙别的事情了,等到要做这个需求的我时候,发现已经 落后版本了,并且有很多文件的冲突,然后就用rebase ...

  2. css文本阴影

    文本阴影-text-shadow text-shadow 属性向文本添加一个或多个阴影.该属性是逗号分隔的阴影列表,每个阴影有两个或三个长度值和一个可选的颜色值进行规定,省略的长度是 0. h-sha ...

  3. First Training

    B B - Local Extrema CodeForces - 888A You are given an array a. Some element of this array ai is a l ...

  4. Python - 翻译Talk Python To Me (和我聊Python) 播客

    “和我聊Python”是一个美国的聊天播客,英文名Talk Python To Me,类似于喜马拉雅的音频课程节目,只不过这个主题是编程语言Python.该节目从2015年的节目到现在,已经超过256 ...

  5. [javascript]各种页面定时跳转(倒计时跳转)代码总结

    (1)使用setTimeout函数实现定时跳转(如下代码要写在body区域内) <script type="text/javascript"> //3秒钟之后跳转到指定 ...

  6. [YII2] 展示页面显示图片 以及手机号隐藏为*和姓名隐藏姓为*,

  7. Fiddler抓取抖音视频

    目录 工具 Fiddler配置 手机端配置 工具 Android 或 ios手机均可 Fiddler 下载地址:https://www.telerik.com/fiddler Windows 操作系统 ...

  8. 数值分析实验之曲线最小二乘拟合含有噪声扰动(python实现)

    一.实验目的 掌握最小二乘法拟合离散数据,多项式函数形式拟合曲线以及可以其他可以通过变量变换转化为多项式的拟合曲线目前待实现功能: 1. 最小二乘法的基本实现. 2. 用不同数据量,不同参数,不同的多 ...

  9. C#多线程(15):任务基础③

    目录 TaskAwaiter 延续的另一种方法 另一种创建任务的方法 实现一个支持同步和异步任务的类型 Task.FromCanceled() 如何在内部取消任务 Yield 关键字 补充知识点 任务 ...

  10. 7、窗口函数 & Windows 的 Operator demo

    代码地址:https://gitee.com/nltxwz_xxd/abc_bigdata 一.窗口函数 在定义了窗口分配器之后,我们需要为每一个窗口明确的指定计算逻辑,这个就是窗口函数要做的事情,当 ...