码迷,mamicode.com
首页 > 其他好文 > 详细

P3022 [USACO11OPEN]Odd degrees G

时间:2020-03-24 09:16:45      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:col   题目   vector   contain   contains   clu   pac   head   example   

题目描述

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_iAi?B_iBi?。数据保证无重边,但不保证连通(即从一个点不一定能到达另一点)。

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

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

下面是一个样例

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

读入输出格式

读入格式

  • 第一行两个整数 NN 和 MM
  • 第二到M+1M+1行,每行描述一条边 有两个整数A_iAi?B_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;
}

P3022 [USACO11OPEN]Odd degrees G

标签:col   题目   vector   contain   contains   clu   pac   head   example   

原文地址:https://www.cnblogs.com/orangeko/p/12556504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!