FZU Problem 2112 Tickets (dfs 欧拉图啊)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2112

Problem Description

You have won a collection of tickets on luxury cruisers. Each ticket can be used only once, but can be used in either direction between the 2 different cities printed on the ticket. Your prize gives you free airfare to any city to start your cruising, and
free airfare back home from wherever you finish your cruising.

You love to sail and don‘t want to waste any of your free tickets. How many additional tickets would you have to buy so that your cruise can use all of your tickets?

Now giving the free tickets you have won. Please compute the smallest number of additional tickets that can be purchased to allow you to use all of your free tickets.

Input

There is one integer T (T≤100) in the first line of the input.

Then T cases, for any case, the first line contains 2 integers n, m (1≤n, m≤100,000). n indicates the identifier of the cities are between 1 and n, inclusive. m indicates the tickets you have won.

Then following m lines, each line contains two integers u and v (1≤u, v≤n), indicates the 2 cities printed on your tickets, respectively.

Output

For each test case, output an integer in a single line, indicates the smallest number of additional tickets you need to buy.

Sample Input

3

5 3

1 3

1 2

4 5

6 5

1 3

1 2

1 6

1 5

1 4

3 2

1 2

1 2

Sample Output

1

2

0

Source

“高教社杯”第三届福建省大学生程序设计竞赛

题意:

给出n个城市和m张票,

求需要额外再买几张票可以用完已经给出的票,每张票只能用一次!

代码如下:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 100017;
vector <int >v[maxn];
int d[maxn];
int vis[maxn];
int k;
int dfs(int x)
{
    if(vis[x])
        return k;
    vis[x] = 1;
    if(d[x]%2 == 1)
        k++;
    for(int i = 0; i < v[x].size(); i++)
    {
        dfs(v[x][i]);
    }
    return k;
}
int main()
{
    int t;
    int n, m;
    scanf("%d",&t);
    while(t--)
    {
        memset(d,0,sizeof(d));
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++)
            v[i].clear();
        int a, b;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d",&a,&b);
            v[a].push_back(b);
            v[b].push_back(a);
            d[a]++;
            d[b]++;
        }
        int tt, kk = 0;
        int ans = 0;
        for(int i = 1; i <= n; i++)
        {
            k = 0;
            if(d[i] == 0 || vis[i])
                continue;
            kk++;//几个分块
            tt = dfs(i);
            //printf("tt::%d\n",tt);
            if(tt > 2)
                tt = (tt-2)/2;
            else
                tt = 0;
            ans += tt;
        }
        //printf("kk::%d\n",kk);
        if(kk > 1)
            ans += (kk-1);
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-09 10:42:45

FZU Problem 2112 Tickets (dfs 欧拉图啊)的相关文章

ACM: FZU 2112 Tickets - 欧拉回路 - 并查集

FZU 2112 Tickets Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Practice Description You have won a collection of tickets on luxury cruisers. Each ticket can be used only once, but can be used in either direction between

FZU Problem 2169 shadow

http://acm.fzu.edu.cn/problem.php?pid=2169 题目大意: S王国有N个城市,有N-1条道路.王都为编号1的城市.叛军驻扎在许多城市.除了王都外有K个城市有军队,这K支军队要向王都进军,并且消灭沿途经过的城市中的叛军.每支军队只能沿着道路走,并且是其所在城市与王都之间的最短路线走.问能够消灭多少叛军? 思路: 有两种方法. 注意到题目只有N-1条边.是一颗树. 我想到的是对编号为1的结点(也就是王都,作为跟结点)进行DFS,一直遍历到树叶为止.沿途若发现有军

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

FZU Problem 2034 Password table (简单模拟题)

这种简单题做了好长时间,我是不是有点逗? 地址:http://acm.fzu.edu.cn/problem.php?pid=2034 不解释了,自己看吧,练手的好题 上个代码吧 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <stdio.h> #include <string.h> #include <stdlib.h>

FZU Problem 2238 Daxia &amp; Wzc&#39;s problem

Daxia在2016年5月期间去瑞士度蜜月,顺便拜访了Wzc,Wzc给他出了一个问题: Wzc给Daxia等差数列A(0),告诉Daxia首项a和公差d; 首先让Daxia求出数列A(0)前n项和,得到新数列A(1); 然后让Daxia求出数列A(1)前n项和,得到新数列A(2); 接着让Daxia求出数列A(2)前n项和,得到新数列A(3); 规律题,首先写出 a.a+d.a+2d.a+3d...这个容易写出 下面一行也容易写出:a.2a+d.3a+3d.... 再下一行,确实难写,但是通过上

FZU Problem 2168 防守阵地 I

http://acm.fzu.edu.cn/problem.php?pid=2168 题目大意: 给定n个数和m,要求从n个数中选择连续的m个,使得a[i]*1+a[i+1]*2+--a[i+m]*m最大 思路: 常规思路是以每个数开始,枚举m个,但是这样会TLE. 可以有O(n)的算法. 例如样例的 n=5 m=3 五个数分别为 2 1 3 1 4 有三种连续的三个数 2 * 1 + 1 * 2 + 3* 3 = 13 1 * 1 + 3 * 2 + 1 * 3= 10 3 * 1 + 1 *

FZU Problem 2062 Suneast &amp; Yayamao

http://acm.fzu.edu.cn/problem.php?pid=2062 题目大意: 给你一个数n,要求求出用多少个数字可以表示1~n的所有数. 思路: 分解为二进制. 对于一个数n,看它二进制有多少位即可. #include<cstdio> int main() { int n; while(~scanf("%d",&n)) { int k=0; while(n) { n>>=1; k++; } printf("%d\n"

FZu Problem 2233 ~APTX4869 (并查集 + sort)

题目链接: FZu Problem 2233 ~APTX4869 题目描述: 给一个n*n的矩阵,(i, j)表示第 i 种材料 和 第 j 种材料的影响值,这个矩阵代表这n个物品之间的影响值.当把这n个物品分成两部分后,每部分内部材料不会相互影响,但是不同部分的材料之间会相互影响.问如何分割使得两部分材料相互之间的最小影响值最大? 解题思路: 材料内部不会影响,那么只需要把影响值小的物品放在同一部分即可,所以用结构体保存物品之间的影响值,然后sort一下,影响值小的物品用并查集放在一个集合,当

FZu Problem 2236 第十四个目标 (线段树 + dp)

题目链接: FZu  Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里面保存所表达区间里面的方案数.先离散化序列(升序排列),建树,然后按照没有sort前的顺序向线段树里面加点,每次查询小于该数的方案数目+1, 就是当前节点插入进去能影响的方案数目.在线段树对应位置加上新增加的数目即可. 1 #include <cstdio> 2 #include <queu