One-Way Reform(欧拉回路)

来源:互联网 发布:股票软件mac版 编辑:程序博客网 时间:2024/05/22 07:48
题意:n个点m条边的无向连通图 ,没有自环没有重边 ,我们要把所有点都定向 ,希望使得尽可能多的点拥有相同的入度与出度 

让你输出满足这个条件的最大点数和每条边最后的定向

欧拉回路有如下定理:

 1.D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度
与入度之差为-1。
2.无向图G存在欧拉通路的充要条件是:G为连通图,并且G仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点。
3.若无向图上改为有向图,使得尽可能多的点拥有相同的入度与出度 ,这些点的数量就是无向图上度数为偶数的数量。
证明如下:
无向图上度数为奇数的点,无论怎么确定方向,均不能使其入度等于出度,可以加一个虚构的点,让这个点与这些度数为奇数的点连一条边,这样一来就都是度数为偶数了,然后再跑一边欧拉回路,然后再把这些虚构的边删掉,可以发现这些边并不影响原来度数为偶数的那些点。

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=205;set<int> g[N];vector<pair<int,int> >ans;void dfs(int u){    while(g[u].size())    {        int v=*g[u].begin();        ans.push_back(make_pair(u,v));        g[u].erase(v);        g[v].erase(u);        dfs(v);    }}int main(){    std::ios::sync_with_stdio(false);    std::cin.tie();    int n,m,u,v,t;    cin>>t;    while(t--)    {        ans.clear();        cin>>n>>m;        for(int i=1;i<=m;i++)        {            cin>>u>>v;            g[u].insert(v);            g[v].insert(u);        }        for(int i=1;i<=n;i++)        {            if(g[i].size()&1)            {                g[0].insert(i);                g[i].insert(0);            }        }        cout<<n-g[0].size()<<endl;        for(int i=1;i<=n;i++)        {            dfs(i);        }        for(int i=0;i<ans.size();i++)        {            if(ans[i].first && ans[i].second)            {                cout<<ans[i].first<<" "<<ans[i].second<<endl;            }        }    }}



原创粉丝点击