zoukankan      html  css  js  c++  java
  • 游历校园 [COGS 614] [欧拉图]

    Description

    刷完牙洗完脸,黄黄同学就要上课去了。可是黄黄同学每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄黄同学想每条路也只走一遍。我们一般人很可能对一些地图是办不到每条路走一遍且仅走一遍的,但是黄黄同学有个传送机,他可以任意地将一个人从一个路口传送到任意一个路口。
    可是,每传送一次是需要耗费巨大的内力的,黄黄同学希望可以用最少的传送次数完成游遍校园,你能帮助他吗 ?
    因为黄黄同学只是游历校园,于是我们可以认为黄黄同学可以从任意点开始,到任意点结束。

    Input

    第一行有一个整数 N ,表示黄黄的校园里一共有多少路口。
    第二行有一个整数 M ,表示路口之间有 M 条路。
    后面 M 行每行两个整数 a 、 b 表示 a 与 b 之间有一条路,且路是双向的。

    Output

    只包括一个整数 s ,表示黄黄同学最少的传送次数。

    Sample Input

    3
    2
    1 2
    2 3

    Sample Output

    0

    Hint

    数据范围:
    对于 100 %的数据,保证 N ≤ 100000 , K ≤ 500000 , 1 ≤ a , b ≤ N 。

    Solution

    请教了数学组的大佬后才会做的...

    对于一个连通块,要完成「一笔画」,度数为寄的点只能为0或2个,而跳一次相当于连一条边。消除两个寄点

    所以当一个连通块寄点数为x>2时,要化成2个时,加的边(跳的次数)=(x-2)/2

    所以bfs解决连通块就行了

    但是注意!无度数的点不要考虑,因为没有边要遍历。

    Code

     1 #include<queue>
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 #define RG register int
     8 #define rep(i,a,b)    for(RG i=a;i<=b;i++)
     9 #define per(i,a,b)    for(RG i=a;i>=b;i--)
    10 #define add(x,y) e[++cnt].v=y,e[cnt].next=head[x],head[x]=cnt
    11 #define inf (1<<30)
    12 #define maxn 100005
    13 #define maxm 500005
    14 using namespace std;
    15 int n,m,sid,cnt,ans;
    16 int head[maxn],vis[maxn],deg[maxn];
    17 vector<int> vec[maxn];
    18 struct E{
    19     int v,next;
    20 }e[maxm<<1];
    21 inline int read()
    22 {
    23     int x=0,f=1;char c=getchar();
    24     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    25     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    26     return x*f;
    27 }
    28 
    29 void bfs(int x)
    30 {
    31     int sum=0;
    32     queue<int> que;
    33     que.push(x),vis[x]=1;
    34     RG u,v;
    35     while(!que.empty())
    36     {
    37         u=que.front(),que.pop();
    38         if(deg[u]&1) ++sum;
    39         for(RG i=head[u];i;i=e[i].next)
    40         {
    41             v=e[i].v;
    42             if(!vis[v])
    43                 vis[v]=1,que.push(v);
    44         }
    45     }
    46     if(sum>2)    ans+=(sum-2)>>1;
    47 }
    48 
    49 int main()
    50 {
    51 
    52     n=read(),m=read();
    53     RG u,v;rep(i,1,m) u=read(),v=read(),add(u,v),add(v,u),++deg[u],++deg[v];
    54     rep(i,1,n)    if(!vis[i]&&deg[i]>0)    bfs(i),ans++;
    55     cout<<ans-1;
    56     return 0;
    57 }
    >>点击查看代码<<
  • 相关阅读:
    mybatis 调用mysql存储过程 带输出输入参数
    MyBatis 通过包含的jdbcType类型和java中对应的数据类型
    大型网站架构之分布式消息队列
    加密解密(2)*客户端,服务器,CA(Certificate Authority),公钥,私钥,证书,签名,验证
    AlertDialog与DialogFragment
    从日期对象中获取(年份、月份、日期、时间等数字)
    LayoutInflater的获取方式
    php——会话控制
    什么是虚假唤醒 spurious wakeup
    Linux互斥锁、条件变量和信号量
  • 原文地址:https://www.cnblogs.com/ibilllee/p/8718378.html
Copyright © 2011-2022 走看看