zoukankan      html  css  js  c++  java
  • 2018/7/28 欧拉路径

    1003 Cover(hdu 6311)

    http://acm.hdu.edu.cn/showproblem.php?pid=6311

    题意:给你一个无向非连通图(王的北疆),要求每个士兵守卫(覆盖)一条路径(空守哨站QAQ),最少需要多少个士兵?每个士兵守卫的疆域(路径)是?

              即给你一个图,问你最少几次一笔画可以画完。

    思路:把每个联通快中度为奇数的点两两相连(留下一对作为欧拉路径的首尾)后,可以构造出这n个点的欧拉路径(一笔画游戏QAQ),把后补的线(id=0)去掉后剩余的几个路径便是每个士兵守卫的那部分疆域。

     官方题解:

    每个连通块显然是独立的。对于一个连通块(除了单个点的),如果奇度数点个数为 k,那么至少需要 max(k/2, 1)条路径。我们将奇度数点两两配对连边,求出欧拉回路,然后把这些边删掉,就可以变成恰好 max(k/2, 1)条路径。
    复杂度 O(m+n)。

    喜大普奔,官方题解说人话了!!!而且思路清晰有理有据,不像百度的题解都是上来就说啊呀这个要用欧拉路径不说为啥。QAQ。。。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int N = 1e5 + 5;
     5 
     6 struct edge{
     7     int from, to, id, vis;
     8 };
     9 vector<edge> e;
    10 vector<int> G[N], ans[N];///num in edge.
    11 vector<int> point, ac;
    12 int n, m, deg[N], vis[N], res;
    13 
    14 void init(){
    15     res = 0;
    16     for(int i = 0; i <= n; i++){
    17         G[i].clear();
    18         ans[i].clear();
    19     }
    20     //point.clear(), ac.clear(),
    21     e.clear();
    22     memset(deg, 0, sizeof deg);
    23     memset(vis, 0, sizeof vis);
    24 }
    25 
    26 void add(int from, int to, int id){
    27     e.push_back(edge{from, to, id, 0});///{}
    28     e.push_back(edge{to, from, -id, 0});
    29     int pos = e.size();
    30     G[from].push_back(pos - 2);
    31     G[to].push_back(pos - 1);
    32     deg[from]++, deg[to]++;
    33 }
    34 void dfs1(int u){
    35     vis[u] = 1;
    36     if(deg[u] & 1) point.push_back(u);
    37     int l = G[u].size();
    38     for(int i = 0; i < l; i++){
    39         edge &ed = e[G[u][i]];
    40         if(!vis[ed.to]) dfs1(ed.to);
    41     }
    42 }
    43 void dfs2(int u){
    44     int l = G[u].size();
    45     for(int i = 0; i < l; i++){
    46         edge &ed = e[G[u][i]];
    47         if(ed.vis) continue;
    48         ed.vis = e[G[u][i]^1].vis = 1;
    49         dfs2(ed.to);
    50         ac.push_back(ed.id);
    51     }
    52 }
    53 
    54 int main()
    55 {
    56     while(~scanf("%d %d", &n, &m)){
    57         init();///
    58         int u, v;
    59         for(int i = 1; i <= m; i++){
    60             scanf("%d %d", &u, &v);
    61             add(u, v, i);
    62         }
    63         for(int i = 1; i <= n; i++){
    64             if(vis[i] || deg[i] == 0) continue;
    65             point.clear();
    66             dfs1(i);
    67             int l = point.size();
    68             for(int j = 2; j < l; j += 2) add(point[j], point[j + 1], 0);
    69             ac.clear();
    70             int t = point.empty()? i: point[0];
    71             dfs2(t);
    72             for(int j = ac.size() - 1; j >= 0; j--){
    73                 if(ac[j] == 0) continue;
    74                 res++;
    75                 while(ac[j] != 0 && j >= 0){
    76                     ans[res].push_back(ac[j]);
    77                     j--;///
    78                 }
    79                 //j++;???don't make any influence.
    80             }
    81         }
    82         printf("%d
    ", res);
    83         for(int i = 1; i <= res; i++){
    84             int l = ans[i].size();
    85             printf("%d", l);
    86             for(int j = 0; j < l; j++) printf(" %d", ans[i][j]);
    87             puts("");
    88         }
    89     }
    90     return 0;
    91 }

    突然就懈怠了,还有一题(笛卡尔树)只看了题解了解了思路就假装补完了。。。感觉补题补得心累,发现队友也看不进去了最终三只选择肥寝。

    PS:竹一楼下水果店和商店暑假不关门开心!买到了汪叽哒蓝朋友口味哒可爱多开心o(* ̄▽ ̄*)ブ~

  • 相关阅读:
    12迭代器
    11(2)Vector(向量)
    11(1) LinkList ---链表
    11集合(Collection<E>) Arraylist
    10异常
    乘法计算过程的模拟
    10 Date详解
    详细的OA系统学习
    8 math类
    Java开发中的23种设计模式详解
  • 原文地址:https://www.cnblogs.com/curieorz/p/9381863.html
Copyright © 2011-2022 走看看