codeforces Div.2 #840D Leha and another game about graph 顶点权值为度数对应奇偶

来源:互联网 发布:淘宝标题关键词测试 编辑:程序博客网 时间:2024/05/22 16:54

原题链接:
codeforces 840D

大意:
给一个无向连通图,不包含子环,允许回路存在。每个点的权值为 didi 的值为 1 ,-1 ,0 的一种。现在要求构造一个子图,要求每个点的权值为 -1 或是 该点的度数模 2 为 d[i]
不存在则输出-1

Limits:
n 3e5

思路:
当时比赛的时候有点乱,没理清楚,题目并不难,但是不是很好打。学习了一个写法。

  • 首先考虑特殊情况,
    只要有 -1 的点存在,一定存在解,原因在于-1不需要度数要求,每个和-1连的点都可以调整,这个性质可以传递到整个图。
    其次当 1 的点为奇数个时,不存在解,这个情况与 不满足的点为奇数个时不存在 等价。
    每次剪边都会产生不满足的点+2或是-2 ,利用这个结论可以证明出来。

  • 如何得到解
    已知可以得到解之后,瞎搞就可以了,注意一点是由于选边会彼此影响,所以需要 dfs序 自底而上处理。
    处理技巧是:
    预处理 -1 的点,把 -1 的点变为 1 和 0 来互补。
    因为每次选边,相当于点权值01的性质变了。
    边编号、起点、终点三元组可以通过vector<pair<int,int> > a[MAXN]实现

if(该边下一个点权值为 1){    该边的两点权值取反;//(1变0,0变1)    选取该边;}

具体实现:

#include <bits/stdc++.h>using namespace std;typedef long long ll;#define mem(s,t) memset(s,t,sizeof(s))#define D(v) cout<<#v<<" "<<v<<endl#define inf 0x3f3f3f3f#define pb push_back#define  pii pair<int,int>//#define LOCALconst int MAXN =3e5+10;int n,m;vector<pii> a[MAXN];vector<int> ans;int d[MAXN],de[MAXN],t=0,s=0;bool vis[MAXN];void dfs(int x,int y){    vis[x]=1;    for(auto u:a[x]){        if(y==u.first) continue;        if(vis[u.first]) continue;        dfs(u.first,x);        if(d[u.first]){            d[u.first]^=1;            d[x]^=1;            ans.pb(u.second);        }    }}int main() {    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        scanf("%d",&d[i]);        if(d[i]==-1) t++;        if(d[i]==1) s++;    }    if(s%2==1&&t==0){        puts("-1");        return 0;    }    for(int i=1;i<=n;i++){        if(d[i]==-1){            d[i]=s%2;            s+=d[i];        }    }    for(int i=1;i<=m;i++){        int x,y;        scanf("%d%d",&x,&y);        a[x].pb({y,i});        a[y].pb({x,i});    }    dfs(1,0);    sort(ans.begin(),ans.end());    printf("%d\n",ans.size());    for(int i=0;i<ans.size();i++){        printf("%d\n",ans[i]);    }    return 0;}
阅读全文
0 0
原创粉丝点击