zoukankan      html  css  js  c++  java
  • P3022 [USACO11OPEN]Odd degrees G

    题目描述

    The cows are being invaded! Their republic comprises N (1 <= N <= 50,000) towns that are connected by M (1 <= M <= 100,000) undirected paths between two towns A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N; A_i != B_i; no duplicate paths will occur). However the republic is not necessarily connected--there may be pairs of towns that are unable to reach each other through the paths.

    The cows know their invaders plan to conduct an inventory of every path within their republic, so they are willing to shut down various paths to make it as difficult as possible for their invaders to do so.

    Please help the cows find a way to shut down a subset of the paths such that each town has an odd number of remaining paths connected to it, or determine if no such subset exists.

    For example, consider the following cow republic:

    1---2 / 3---4 If we keep the paths 1-3, 2-3, and 3-4, and remove the path 1-2, then towns 1, 2, and 4 will be an endpoint of exactly one path, whereas town 3 will be an endpoint of three paths:

    1 2 / 3---4

    输入格式

    * Line 1: Two space-separated integers: N and M

    * Lines 2..M+1: Line i+1 contains two space-separated integers: A_i and B_i

    输出格式

    * Line 1: A single integer that is the number of paths to keep. If no subset exists output only a single line with the integer -1.

    * Lines 2..K+1: Each line contains an index of an path to keep, in the range 1..M. These indices must be pairwise distinct.

    题意翻译

    题意

    牛们正在被入侵。 有NN个点,由MM条无向边连接。 无向边从A_iAiB_iBi。数据保证无重边,但不保证连通(即从一个点不一定能到达另一点)。

    牛知道入侵他们的人正计划清点所有的边,所以他们想切掉一些边使入侵者的计划尽可能的困难

    请找出一个方法,留下一些边,使每个点都只有奇数条边与之连接。并输出留下的边的方案。

    下面是一个样例

    1---2
      /
      3---4
    我们把1——2那条边拆掉, 就会变成下图
    1   2
      /
      3---4
    对于每个点都只有奇数条边连接,符合题意
    

    读入输出格式

    读入格式

    • 第一行两个整数 NN 和 MM
    • 第二到M+1M+1行,每行描述一条边 有两个整数A_iAiB_iBi

    输出格式

    • 第一行一个整数 剩下边的数量,如果不可能请输出-1
    • 之后每一行一个数,边的编号(按输入顺序来)。

    感谢@ToBiChi 提供翻译

    输入输出样例

    输入 #1
    4 4 
    1 2 
    2 3 
    3 1 
    3 4 
    
    输出 #1
    3 
    2 
    3 
    4 
    

    说明/提示

    感谢@cn:苏卿念 提供的Special Judge

    思路

      在图上搜索的过程中由叶子的连边情况开始更新,如果叶子上边数为奇数则证明当前选择的边不需要加入叶子的边,逆着dfs序来更新即可

    CODE

    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;

    const int inf = 0x3f3f3f3f;

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    namespace _buff {
        const size_t BUFF = 1 << 19;
        char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
        char getc() {
            if (ib == ie) {
                ib = ibuf;
                ie = ibuf + fread(ibuf, 1, BUFF, stdin);
            }
            return ib == ie ? -1 : *ib++;
        }
    }

    int qread() {
        using namespace _buff;
        int ret = 0;
        bool pos = true;
        char c = getc();
        for (; (< '0' || c > '9') && c != '-'; c = getc()) {
            assert(~c);
        }
        if (== '-') {
            pos = false;
            c = getc();
        }
        for (; c >= '0' && c <= '9'; c = getc()) {
            ret = (ret << 3) + (ret << 1) + (^ 48);
        }
        return pos ? ret : -ret;
    }

    const int maxn = 1e5 + 7;

    int n, m, cnt;

    int edge[maxn << 1], head[maxn << 1], nxt[maxn << 1];
    int id[maxn << 1];

    void BuildGraph(int u, int v, int idx) {
        ++cnt;
        edge[cnt] = v;
        nxt[cnt] = head[u];
        head[u] = cnt;
        id[cnt] = idx;
    }

    vector<int> ans;
    bool vis[maxn];

    bool dfs(int u, int fa, int idx) {
        int du = 0;
        vis[u] = 1;
        for ( int i = head[u]; i; i = nxt[i] ) {
            int v = edge[i];
            if(vis[v] || v == fa)
                continue;
            if(dfs(v, u, id[i]))
                ++du;
        }
        if(du & 1) {
            return false;
        }
        ans.push_back(idx);
        return true;
    }

    int main()
    {
        read(n);read(m);
        for ( int i = 1; i <= m; ++) {
            int u, v;
            read(u);read(v);
            BuildGraph(u, v, i);
            BuildGraph(v, u, i);
        }
        for ( int i = 1; i <= n; ++) {
            if(vis[i])
                continue;
            if(dfs(i, 0, 0)) {
                puts("-1");
                return 0;
            }
        }
        int d = ans.size();
        cout << d << endl;
        for ( int i = 0; i < d; ++) {
            cout << ans[i] << endl;
        }
        return 0;
    }
  • 相关阅读:
    共轭梯度法
    OpenGLGLUT教程(十一) GLUT子菜单
    怎样让函数返回数组
    OpenGLGLUT教程(九) GLUT鼠标
    OpenGLGLUT教程(七) GLUT高级键盘控制
    OpenGLGLUT教程(六) GLUT场景漫游
    OpenGLGLUT教程(五) GLUT键盘控制
    OpenGLGLUT教程(八) GLUT场景漫游II
    dos指令 批处理文件
    新的启程!
  • 原文地址:https://www.cnblogs.com/orangeko/p/12556504.html
Copyright © 2011-2022 走看看