hdu 3472 HS BDC(混合路的欧拉路径)

这题是混合路的欧拉路径问题。

1.判断图的连通性,若不连通,无解。

2.给无向边任意定向,计算每个结点入度和出度之差deg[i]。deg[i]为奇数的结点个数只能是0个或2个,否则肯定无解。

3.(若存在2个deg[i]为奇数的结点,则在两点连一条流量为1的边,方向任意)设立源点s和汇点t(自己另外定两个点),若某点i入度<出度,连边(s,i,-deg[i]/2),若入度>出度,连边(i,t,deg[i]/2);对于任意定向的无向边(i,j,1)。

5.若从S发出的边全部满流,证明存在欧拉回路(路径),否则不存在。

view code#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int INF = 1<<30;
const int N = 2010;
int _,cas=1, n, fa[30], pre[30], deg[30], s, t, d[30];
int cur[30];
bool vis[30];

struct edge
{
    int u, v, cap, next;
    edge() {}
    edge(int u, int v, int w, int next):u(u),v(v),cap(w),next(next) {}
}e[N<<1];
int ecnt;

void addedge(int u, int v, int w)
{
    e[ecnt] = edge(u, v, w, pre[u]);
    pre[u] = ecnt++;
    e[ecnt] = edge(v, u, 0, pre[v]);
    pre[v] = ecnt++;
}

int find(int x)
{
    return x==fa[x]?x:(fa[x]=find(fa[x]));
}

void Union(int u, int v)
{
    u = find(u), v= find(v);
    if(u==v) return ;
    fa[u] = v;
}

bool is_ok()
{
    for(int i=0; i<26; i++) if(vis[i] && find(i)!=find(s)) return false;
    int res = 0;
    for(int i=0; i<26; i++) if(deg[i]%2){
        res++;
        if(res==1) s = i;
        else t = i;
    }
    return res==0 || res==2;
}

bool BFS()
{
    memset(vis, 0, sizeof(vis));
    queue<int >q;
    q.push(s);
    d[s] = 0, vis[s]=1;
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        for(int i=pre[u]; ~i; i=e[i].next)
        {
            int v = e[i].v;
            if(!vis[v] && e[i].cap>0)
            {
                vis[v] = 1;
                d[v] = d[u] +1;
                q.push(v);
            }
        }
    }
    return vis[t];
}

int DFS(int u, int c)
{
    if(u==t || c==0) return c;
    int flow=0, f;
    for(int &i=pre[u]; ~i; i=e[i].next)
    {
        int v = e[i].v;
        if(d[v]==d[u]+1 && (f=DFS(v, min(c, e[i].cap)))>0)
        {
            e[i].cap -= f;
            e[i^1].cap += f;
            flow += f;
            c -= f;
            if(c==0) break;
        }
    }
    return flow;
}

int Maxflow()
{
    int flow = 0;
    while(BFS())
    {
        memcpy(cur, pre, sizeof(pre));
        flow += DFS(s, INF);
    }
    return flow;
}

void solve()
{
    scanf("%d", &n);
    memset(pre, -1, sizeof(pre));
    memset(deg, 0, sizeof(deg));
    memset(vis, 0, sizeof(vis));
    for(int i=0; i<27; i++) fa[i] = i;
    ecnt = 0;
    int rev; char str[27];
    for(int i=0; i<n; i++)
    {
        scanf("%s%d", str, &rev);
        int u = str[0]-‘a‘,  v = str[strlen(str)-1]-‘a‘;
        deg[u]--; deg[v]++;
        vis[u] = vis[v] = true;
        s = u;
        if(rev) addedge(u, v, 1);
        Union(u,v);
    }
    t = -1;
    printf("Case %d: ", cas++);
    if(!is_ok()) {
        puts("Poor boy!");
        return ;
    }
    if(t!=-1) addedge(t, s, 1);
    s = 26, t = 27;
    int fulflow = 0, flow;
    for(int i=0; i<26; i++)
    {
        if(deg[i]==0) continue;
        if(deg[i]<0) addedge(s, i, -deg[i]/2);
        else addedge(i, t, deg[i]/2), fulflow+=deg[i]/2;
    }
    flow = Maxflow();
    puts(flow==fulflow?"Well done!":"Poor boy!");
}

int main()
{
//    freopen("in.txt", "r", stdin);
    cin>>_;
    while(_--) solve();
    return 0;
}

hdu 3472 HS BDC(混合路的欧拉路径)

时间: 2024-10-13 03:40:46

hdu 3472 HS BDC(混合路的欧拉路径)的相关文章

hdu 3472 HS BDC 混合欧拉 网络流

题意就是问能否将给定的几个单词全部连接起来,两个单词能连接是当前一个单词的最后一个字母等于后一个单词的首字母.还有一些单词反向也没有关系. 建图,每输入一个单词,只看他的首尾字母,连接一条首字母到尾字母的有向边,如果他可以反向,那么再反向建立一条边,即该边是无向边.然后就是一个混合欧拉了. 还有一个注意的地方,就是可能是欧拉道路,这时只要在添加一条边连接两个奇度节点就好. #include <iostream> #include <cstdio> #include <cstr

HDU 3472 HS BDC(混合欧拉图(使用最大流))模板

HS BDC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 980    Accepted Submission(s): 398 Problem Description IELTS is around the corner! love8909 has registered for the exam, but he still hasn

hdu3472 HS BDC --- 混合图欧拉回路

讲的很好的资料: 点击打开链接 点击打开链接 #include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include &l

HS BDC (hdu 3472 混合图的欧拉回路)

HS BDC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 974    Accepted Submission(s): 395 Problem Description IELTS is around the corner! love8909 has registered for the exam, but he still hasn

hdu 3472 混合图的欧拉路径

HS BDC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 964    Accepted Submission(s): 390 Problem Description IELTS is around the corner! love8909 has registered for the exam, but he still hasn’

混合图欧拉回路(hdoj3472 HS BDC)

欧拉回路基础知识戳这里 混合图:就是图里面有的边是有向边,有的边是无向边,组成的图叫做混合图. 要判混合图是否满足欧拉回路,首先必须满足欧拉图的条件 1:欧拉回路要求所有点的度数必须都为偶数,欧拉道路要求所有点的度数两个奇数. 2:给无向的边定向,首先任意定向,这些便之间网络流建边from到to容量为1,然后对于当前入度大于出度的点y,说明有d = (入度-出度)/2的边需要变成相反方向,我们这里不进行变向,而是用一个网络流的超级汇点T,给其建边y到T,容量为d. 然后对于当前出度大于入度的点x

欧拉除了函数,还有个回路----图论之路之欧拉路径欧拉回路

首先我们来百度一下,欧拉路径以及回路的定义: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径.若该路径是一个圈,则称为欧拉(Euler)回路. 具有欧拉回路的图称为欧拉图(简称E图).具有欧拉路径但不具有欧拉回路的图称为半欧拉图. 通俗来说,就是欧拉路径就是图中的每条边经过却只经过一次的路径,而最后回到起点的路径就是欧拉回路. 那给你一个图怎么判断存不存在,欧拉路径或者欧拉回路呢 首先,判断图是不是连通的,这个就很简单了,dfs或者并查集都可以. 然后就是根据定理 欧

hdu 4850 Wow! Such String! 构造 或 欧拉路径并改写成非递归版本

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4850 跟这道题也算是苦大仇深了... 题意:构造一个由26个小写字母组成的.无长度为4的重复子串的字符串(要求出能构造出的最大长度) 符合要求的长度为4的字符串有4^26个 容易猜最大长度是:4^26+3 = 456979 比赛的时候想法是要让各个字母出现得尽量“均匀” 用了一个cnt数组记录26个字母出现的次数 每次都选择出现次数最小的.不与前面重复的字母加上去 然而稍微写得有点歪,最后构造出了长

HDU 3535 AreYouBusy (混合背包)

题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下,可以得到的最大的乐趣是多少,如果不能满足条件就输出-1 题解:二维01背包 dp[i][j]:前i组物品我们拥有j的价值时最大可获得的乐趣 0:我们需要先把dp[i]所有赋值为负无穷,这样就只能最少选一个才能改变负无穷 1:我们不需要:dp[i][j-ci]+gi(在此组中再选一个),这样就一定最