E. One-Way Reform

来源:互联网 发布:java获取webapp下路径 编辑:程序博客网 时间:2024/05/17 22:53

题目链接http://codeforces.com/problemset/problem/723/E

PS:这个题花了我一下午 呜呜呜。参考了别人的文章最终搞明白了原理 原文好多我不知道的东西 就一点一点查明白,到最后的AC 很是欣慰啊!

题意:

给你一个图:1无向图 2 每一对点之间只存在一条路径 3.不存在自己到自己的路径
让你求出 入度和出度相等的城市 然后输出所有的联通路径 每条边只能出现一次

解题思路:

找到出度和出度相等的城市很好找 关键是你要输出这个路径 这个路径不是随便输出的 因为如果处理不好度为奇数的城市 你会把一条完整的路径給分开 所以这就用得到了 欧拉回路的思想了。
假设一个图的度为M (必定为偶数) 因为每一条边的度为2 。 那么奇数度的城市 为k个 那么k必为偶数
为什么呢 因为总度为偶数。。。。所以我们只需要添加一个城市 让奇数度的点与他相连 那么就保证了整个图上的每一个点的度为偶数 那么必定 有一条回路 包含了 新加的这个点 那么我们只需要再打印的时候过滤这个点就好了 那么这条路径就是完整而且没有被分割的 .。。
这个题用到了dfs+欧拉回路(我只学会了这一种 如果还有其他的方法我会后续贴上)

AC代码

#include<iostream>#include<cstdio>#include<cstring>#include<set>using namespace std;const int maxn= 200+10;set<int> map1[maxn];//此图为稀疏图 所以我们用邻接矩阵存储int du[maxn];//保存了每一个城市的度int tc,n,m;void init(){    memset(du,0,sizeof(du));    for(int i=0;i<maxn;i++)        map1[i].clear();//清空集合内容}void dfs(int u){    while(map1[u].size())    {        int v=*map1[u].begin();        map1[u].erase(v);        map1[v].erase(u);        if(u!=n+1&&v!=n+1)//如果这条边包含我们自己加上的那个点 就过滤            printf("%d %d\n",u,v);        dfs(v);    }}int main(){    int u,v;    cin>>tc;    while(tc--)    {        init();        cin>>n>>m;        while(m--)        {            cin>>u>>v;            du[u]++;//记录这个城市的度            du[v]++;            map1[u].insert(v);            map1[v].insert(u);        }        int c_js_du=0;        for(int i=1;i<=n;i++)        {            if(du[i]&1)//这就是骚操作了 按位与  只要是奇数 那么二进制最后一位必为1             {                c_js_du++;                map1[i].insert(n+1);                map1[n+1].insert(i);            }        }        printf("%d\n",n-c_js_du);        for(int i=1;i<=n;i++)        dfs(i);//因为可能存在不联通的边 所以我们每一个点都要遍历一遍    }    return 0; } 

UNFINISHED! 还要继续更新后续方法

阅读全文
0 0