Bigraph Extension HDU - 7135 
有一个2*n(n为偶数,n < 1e3)个点的二分图,已经连好了m条边,这m条边保证任意两条边不含公共点。
求最少添加多少条边,使得这个图任意两点连通,且最长简单路径所含边数 > n。输出最小字典序的方案。
 
 
 
``
`
 
 
 
 
`
 
 
``
``
``
思路,不难想到是要建一个2*n的环。那么此题关键点是要构造字典序最小的方案,那么我们每次找字典序最小的点来建边即可。用并查集维护,保证连的点不成环。
那么对于最后一条边,也就是两个度数为1的点连边使图成环即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
   | 
 
 
 
 
  #include<bits/stdc++.h> using namespace std; #define Debug(x) cout<<#x<<':'<<x<<endl #define INF 0x7fffffff typedef long long ll; typedef pair<ll,ll> P; const ll maxn=2e3+11; vector<P> ans; ll fa[maxn],d[maxn]; ll n,m; ll found(ll x){return fa[x]==x?x:fa[x]=found(fa[x]);} void solve1(){     ll e=0;     for(ll i=1;i<=n;i++){         while(d[i]<2){             for(ll j=n+1;j<=2*n;j++){                 if(d[j]<2){                     ll fi=found(i),fj=found(j);                     if(fi==fj)  continue;                     d[i]++,d[j]++;                     ans.push_back({i,j});                                          fa[fi]=fj;                     e++;                     if(e>=2*n-m-1)  return ;                     break;                 }             }         }     } } void solve2(){     ll u,v;     for(ll i=1;i<=2*n;i++){         if(d[i]==1){u=i;break;}     }     for(ll i=1;i<=2*n;i++){         if(d[i]==1 && i!=u){v=i;break;}     }     ans.push_back({u,v});     cout<<ans.size()<<endl;     for(auto i=ans.begin();i!=ans.end();i++){         cout<<(*i).first<<" "<<(*i).second-n<<endl;     }     return ; } int main(){     ios::sync_with_stdio(false);     cin.tie(0);     ll ca;cin>>ca;     while(ca--){         cin>>n>>m;         for(ll i=1;i<=2*n;i++)  fa[i]=i;         ans.clear();memset(d,0,sizeof(d));         for(ll i=1;i<=m;i++){             ll u,v;cin>>u>>v;             v=v+n;             d[u]++,d[v]++;             fa[u]=v;         }         solve1();         solve2();     }     return 0; }
 
  |