hdu 3018 Ant Trip

点击打开链接hdu 3018

题意: 给定一个n个点m条边的无向图求有几条欧拉道路或者欧拉回路
思路: 欧拉回路
分析:
1 给定一个图判断欧拉道路的条数,那么对于一个图有n个连通分支来说那么至少有n条欧拉道路或者欧拉回路
2 那么我们首先应该利用并查集来求出有几个连通分支
3 求出有几个连通分支后,我们就要去求每一个连通分支里面有几条欧拉道路或者欧拉回路,那么很明显是通过度数来判断,如果度数都是偶数那么当前的连通分支就是一个欧拉回路,那么如果有奇数点,那么欧拉道路的个数就是(奇数点个数+1)/2

代码:

#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 100010;
int n , m;
int degree[MAXN] , father[MAXN] , num[MAXN];
bool vis[MAXN];

void init(){
    memset(vis , false , sizeof(vis));
    memset(degree , 0 , sizeof(degree));
    memset(num , 0 , sizeof(num));
    for(int i = 1 ; i <= n ; i++)
       father[i] = i;
}

int find(int x){
    if(father[x] != x)
        father[x] = find(father[x]);
    return father[x];
}

int solve(){
    int ans = 0;
    set<int>s;
    s.clear();
    for(int i = 1 ; i <= n ; i++)
        if(vis[i])
           s.insert(find(i));
    for(int i = 1 ; i <= n ; i++)
       if(degree[i]&1)
          num[find(i)]++;
    set<int>::iterator it;
    for(it = s.begin() ; it != s.end() ; it++){
       if(!num[*it])
          ans++;
       else
          ans += (num[*it]+1)/2;
    }
    return ans;
}

int main(){
    int x , y;
    while(scanf("%d%d" , &n , &m) != EOF){
         init();
         for(int i = 0 ; i < m ; i++){
            scanf("%d%d" , &x , &y);
            degree[x]++;
            degree[y]++;
            vis[x] = true;
            vis[y] = true;
            father[find(x)] = find(y);
         }
         printf("%d\n" , solve());
    }
    return 0;
}
时间: 2024-10-31 06:03:24

hdu 3018 Ant Trip的相关文章

HDU 1535 Invitation Cards:多源点到单点最短路

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题目: Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1044    Accepted Submission(s): 459 Problem Description In the age of te

HDU 2962 Trucking:二分+带限制最短路

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2962 题目: Trucking Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1211    Accepted Submission(s): 428 Problem Description A certain local truckin

算法:uva 1484 Alice and Bob&#039;s Trip (树形dp)

题意 给一棵n个结点的树,结点编号为0~n-1,顶点是0 每条边都有一个权值. Alice和Bob初始位 置在顶点,要往下一直走到叶子结点. 第一次是由Bob选择走向哪个子结点,第二次轮到Alice,依次轮流 下去... 每走过一条边就会获得相应的权值,Bob希望所走的路径总权值越大越好,而Alice希望越小越好 每次他们都会选择最优解. 最终总权值要在范围[L,R]之内. 问最终Bob希望的最大权值是多少? 思路 f(u, 0)表示第u点由Bob选时的最大值 f(u, 1)表示第u点由Alic

hdu 1527

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 hint:威佐夫博弈 基本类似于模板 #include <iostream> #include <cmath> #include <cstdio> using namespace std; const double q = (1 + sqrt(5.0)) / 2.0; // 黄金分割数 int Wythoff(int a, int b) { if (a > b)

hdu 2551 竹青遍野

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2551 hint:就是读懂题就行了 #include <iostream> #include <cstdio> using namespace std; typedef long long LL; LL data[1005]; int main() { data[0]=0; for(int i=1; i<1005; i++) data[i]+=data[i-1]+i*i*i; LL

hdu 2054 A == B?

http://acm.hdu.edu.cn/showproblem.php?pid=2054 此题巨坑,刚开始我以为是简单的水题,就用strcmp过, but错了,后来经过我苦思冥想,结果还有几组数据 0.0 和 0,1.000和1.0 , 但是我不太确定前面的0是不是有作用我还是写了,但是有人过的时候,前面的0没考虑比如: 002和2可能是相等的,也可能是不想等的所以不用判断,只能说明hdu数据不是很强啊,嘿嘿 代码如下: #include <iostream> #include <c

hdu 4430 Yukari&#039;s Birthday

点击打开链接hdu 4430 思路:枚举r+二分k 分析: 1 题目要求的是找到一组最小的r*k,如果r*k相同那么就找r最小的. 2 很明显k>=2,根据n <= 10^12,那么可以知道r的最大值r<50,所以只要枚举枚举r的值,然后二分k的大小找到所有的解,存入一个结构体里面,然后在对结构体排序,那么这样就可以得到最后的ans 3 注意题目说了中心点最多一个蜡烛,所以写二分的时候应该注意判断的条件: 4 还有可能计算得到结果超了long long直接变成负数所以应该对或则个进行判断

hdu 1238 Substrings

点击打开链接hdu 1238 思路:kmp+暴力枚举子串 分析: 1 题目要求找到一个子串x,满足x或x的逆串是输入的n个字符串的子串,求最大的x,输出x的长度 2 题目的n最大100,每一个字符串的最大长度为100,那么暴力枚举子串就是o(n^2)才10000肯定是不会超时的,但是由于这里涉及到了逆串的问题,所以我们应该还要求出n个子串的逆串,然后在求最大的x. 代码: #include<iostream> #include<algorithm> #include<cstd

hdu 1857 Word Puzzle

点击打开链接hdu 1857 思路:字典树 分析: 1 题目要求的是给定的单词第一个字母在这个矩形里面的最小的坐标 2 矩形的最大500*500,单词的来源有三个方向,并且单词的起点和终点在矩形之内都是可能的.所以的如果利用枚举矩形之内的单词,那么肯定是超内存的 3 所以我们必须考虑另一种的方法就是对单词进行建字典树,那么我们只要去枚举单词的可能的起点,然后进行查找相应的单词是不是在树上,如果是的话就标记一下当前的坐标. 4 注意由于单词的来源有三个方向,但是因为要求的如果下相同的情况下要求坐标