hdu3472 混合欧拉
题意:
给你一些字符串,有的字符串反过来也有意义,题目问给的这n个字符串是否可以首尾相连,组成一个串。
思路:
算是混合欧拉的基础题目了,混合欧拉就是专门处理这类问题的,先说下混合欧拉的大体步骤。
(1) 判断整个图是否连通,如果不连通直接不行(方法随意,并查集搜索什么的都行)
(2) 看度数差为奇数的有多少个,只能有0个或者两个,其他的都不行。
(3) 如果度数差有奇数的有两个,那么一定一个是正的v1,一个是负的v2,add(v1 ,v2 ,1);
(4) 如果方向随意的边,那么我们随意建立一条就行add(a ,b ,1),方向固定的不用管
(5) 虚拟超级远点s,超级汇点e,然后所有度数为负数的add(s ,i ,-du[i]/2),所有为 正的add(i ,e ,du[i]/2);
(6) 最后一遍最大流,看是否满流,如果满流,那么就是有解,否则无解。
至于为什么费用留可以这样求,等比赛回来再来详细补充这个问题。
#include<queue>
#include<stdio.h>
#include<string.h>
#define N_node 30
#define N_edge 10000
#define INF 100000000
using namespace std;
typedef struct
{
int to ,next ,cost;
}STAR;
typedef struct
{
int x ,t;
}DEP;
STAR E[N_edge];
DEP xin ,tou;
int list[N_node] ,listt[N_node] ,tot;
int du[N_node] ,deep[N_node];
int mer[N_node];
void add(int a, int b ,int c)
{
E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot;
E[++tot].to = a;
E[tot].cost = 0;
E[tot].next = list[b];
list[b] = tot;
}
int minn(int x ,int y)
{
return x < y ? x : y;
}
int finds(int x)
{
return x == mer[x] ? x : mer[x] = finds(mer[x]);
}
bool BFS_Deep(int s ,int t ,int n)
{
memset(deep ,255 ,sizeof(deep));
queue<DEP>q;
xin.x = s ,xin.t = 0;
q.push(xin);
deep[xin.x] = xin.t;
while(!q.empty())
{
tou = q.front();
q.pop();
for(int k = list[tou.x] ;k ;k = E[k].next)
{
xin.x = E[k].to;
xin.t = tou.t + 1;
if(deep[xin.x] != -1 || !E[k].cost) continue;
deep[xin.x] = xin.t;
q.push(xin);
}
}
for(int i = 0 ;i <= n ;i ++)
listt[i] = list[i];
return deep[t] != -1;
}
int DFS_Flow(int s ,int t ,int flow)
{
if(s == t) return flow;
int nowflow = 0;
for(int k = listt[s] ;k ;k = E[k].next)
{
int to = E[k].to;
int c = E[k].cost;
listt[s] = k;
if(deep[to] != deep[s] + 1 || !c) continue;
int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
nowflow += tmp;
E[k].cost -= tmp;
E[k^1].cost += tmp;
if(nowflow == flow) break;
}
if(!nowflow) deep[s] = 0;
return nowflow;
}
int DINIC(int s ,int t ,int n)
{
int Ans = 0;
while(BFS_Deep(s ,t ,n))
{
Ans =+ DFS_Flow(s ,t ,INF);
}
return Ans;
}
int main ()
{
int n ,i ,j ,a ,b ,c;
int mark[30];
int t ,cas = 1;
char str[30];
scanf("%d" ,&t);
while(t--)
{
scanf("%d" ,&n);
memset(list ,0 ,sizeof(list)) ,tot = 1;
memset(du ,0 ,sizeof(du));
memset(mark ,0 ,sizeof(mark));
for(i = 1 ;i <= 26 ;i ++) mer[i] = i;
for(i = 1 ;i <= n ;i ++)
{
scanf("%s %d" ,str ,&c);
a = str[0] - 'a' + 1;
b = str[strlen(str)-1] - 'a' + 1;
du[a] -- ,du[b] ++;
mark[a] = mark[b] = 1;
mer[finds(a)] = finds(b);
if(c) add(a ,b ,1);
}
int sum = 0;
for(i = 1 ;i <= 26 && sum <= 2;i ++)
if(finds(i) == i && mark[i]) sum ++;
printf("Case %d: " ,cas ++);
if(sum != 1)
{
puts("Poor boy!");
continue;
}
sum = 0;
int v1 ,v2;
for(i = 1 ;i <= 26 ;i ++)
{
if(du[i] % 2 && du[i] < 0) v1 = i ,sum ++;
if(du[i] % 2 && du[i] > 0) v2 = i ,sum ++;
}
if(sum != 0 && sum != 2)
{
puts("Poor boy!");
continue;
}
if(sum == 2)
{
add(v1 ,v2 ,1);
du[v1] -- ,du[v2] ++;
}
sum = 0;
for(i = 1 ;i <= 26 ;i ++)
{
if(!mark[i]) continue;
if(du[i] < 0) add(0 ,i ,-du[i]/2) ,sum -= du[i]/2;
else add(i ,27 ,du[i]/2);
}
DINIC(0 ,27 ,27) == sum ? puts("Well done!"):puts("Poor boy!");
}
return 0;
}
hdu3472 混合欧拉的更多相关文章
- hdu4067 费用流(混合欧拉的宽展和延伸)
题意: 给以一个图,每个有向边都有两个权值,a,b其中a是保留这条边的花费,b是删除这条边的花费,让你删去一些边使图满足一下要求: (1)只有一个起点和一个终点 (2)所有的边都是又向的 ...
- hdu3472 混合图判断欧拉通路
对于欧拉回路,先判断出度入度的差是否为偶数,然后最大流一次. 此题是判断有无欧拉通路,前提要判断图是否连通,然后欧拉通路的条件:要么出入度差没有奇数,或者只有2个点. 所以先统计差为奇数的个数,如果不 ...
- hdu2588 GCD (欧拉函数)
GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数. (文末有题) 知 ...
- BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]
2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 2553 Solved: 1565[Submit][ ...
- BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4436 Solved: 1957[Submit][Status][Discuss ...
- Euler-Maruyama discretization("欧拉-丸山"数值解法)
欧拉法的来源 在数学和计算机科学中,欧拉方法(Euler method)命名自它的发明者莱昂哈德·欧拉,是一种一阶数值方法,用以对给定初值的常微分方程(即初值问题)求解.它是一种解决常微分方程数值积分 ...
- COGS2531. [HZOI 2016]函数的美 打表+欧拉函数
题目:http://cogs.pw/cogs/problem/problem.php?pid=2533 这道题考察打表观察规律. 发现对f的定义实际是递归式的 f(n,k) = f(0,f(n-1,k ...
- poj2478 Farey Sequence (欧拉函数)
Farey Sequence 题意:给定一个数n,求在[1,n]这个范围内两两互质的数的个数.(转化为给定一个数n,比n小且与n互质的数的个数) 知识点: 欧拉函数: 普通求法: int Euler( ...
- 51Nod-1136 欧拉函数
51Nod: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1136 1136 欧拉函数 基准时间限制:1 秒 空间限制: ...
随机推荐
- 翻译:《实用的Python编程》03_04_Modules
目录 | 上一节 (3.3 错误检查) | 下一节 (3.5 主模块) 3.4 模块 本节介绍模块的概念以及如何使用跨多个文件的函数. 模块和导入 任何一个 Python 源文件都是一个模块. # f ...
- 【Azure 服务总线】Azure Service Bus中私信(DLQ - Dead Letter Queue)如何快速清理
在博文ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题一文中,介绍了服务总线产生私信的原因及可以通过代码的方式来清楚私信队列中的消息,避免长期占用空间(因为私信中 ...
- 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法
剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...
- 2020年12月-第02阶段-前端基础-CSS初识
CSS层叠样式表 理解 css的目的作用 css的三种引入方式 1.HTML的局限性 说起HTML,这其实是个非常单纯的家伙, 他只关注内容的语义, 比如`<h1>`表明这是一个大标题,用 ...
- HTB系列之七:Bastard
出品|MS08067实验室(www.ms08067.com) 这次挑战的是 HTB 的第7台靶机:Bastard 技能收获: PHP Unserilaize CMS Version Identify ...
- 「POJ Challenge」生日礼物
Tag 堆,贪心,链表 Solution 把连续的符号相同的数缩成一个数,去掉两端的非正数,得到一个正负交替的序列,把该序列中所有数的绝对值扔进堆中,用所有正数的和减去一个最小值,这个最小值的求法与「 ...
- go语言实现数组去重
import ( "fmt" ) func main() { a := []int{2, 1, 2, 5, 6, 3, 4, 5, 2, 3, 9} z := Rm_duplica ...
- Java 树结构实际应用 四(平衡二叉树/AVL树)
平衡二叉树(AVL 树) 1 看一个案例(说明二叉排序树可能的问题) 给你一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST), 并分析问题所在. 左边 BST 存在的问题分析: ...
- P2089_烤鸡(JAVA语言)
题目背景 猪猪hanke得到了一只鸡 题目描述 猪猪Hanke特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke吃鸡很特别,为什么特别呢?因为他有10种配料(芥末.孜然等),每种配料可以放1-3克, ...
- 从本质彻底精通Git——4个模型1个周期1个史观1个工作流
一.什么是Git? Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是Linus Torvalds为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软 ...