【UVa 1670/Uvalive 5920】 Kingdom Roadmap 图论
2018-03-09 23:13
531 查看
老年人需要大一点的字体。
紫书习题11-17 NEERC2011
给定一棵树,然后让你加入尽量少的边,使得整张图双连通。
这个uva1670好像数据错了,非常难受,怎么搞都过不去,然后网上现有的题解都是各种奇技淫巧,非常奇怪。
所以自己想了想然后还是自己写了一个,虽然wa了无数次,最后还是在Uvalive5920获得了一个AC,也算是不枉花费的时间了。
先上代码:#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mem(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef pair<int,int> pii;
const int mn=1e5+5;
int n,root;
int f[mn];
vector<int> g[mn],son[mn],leaf;
vector<pii> ans;
void dfs(int x,int fa){
f[x]=fa;
for(auto i:g[x]){
if (i==fa) continue;
dfs(i,x);
}
if (g[x].size()==1){
leaf.pb(x);
if (leaf.size()==3){
int u=leaf[1];
ans.pb(pii(leaf[0],x));
leaf.clear();
leaf.pb(u);
}
}
}
int main() {
while(~scanf("%d",&n)){
ans.clear();
for(int i=1;i<=n;i++) g[i].clear(),son[i].clear(),f[i]=0;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].pb(v);
g[v].pb(u);
}
if (n==2){
puts("1\n1 2");
}
for(int i=1;i<=n;i++){
if (g[i].size()>1) {
root=i;
break;
}
}
dfs(root,0);
if (leaf.size()==2) {
int u=leaf.back();
int v=*leaf.begin();
leaf.clear();
ans.pb(pii(u,v));
}
for(int i:leaf) ans.pb(pii(root,i));
leaf.clear();
//answer
printf("%d\n",ans.size());
for(auto i:ans) printf("%d %d\n",i.first,i.second);
}
return 0;
}我们先随便选一个度数大于2的点作为树根,然后从该树根延展出去。
显然,直接延展出去的每一条边都是一座桥。
为了去除连接每棵子树的根到更上层的桥,每棵子树应该预留下一个点(连上去),所以每棵子树都要留一个点或者两个点(三个点的时候就可以连接两个点了),这样一步步上去,搞搞好就ac辣。
紫书习题11-17 NEERC2011
给定一棵树,然后让你加入尽量少的边,使得整张图双连通。
这个uva1670好像数据错了,非常难受,怎么搞都过不去,然后网上现有的题解都是各种奇技淫巧,非常奇怪。
所以自己想了想然后还是自己写了一个,虽然wa了无数次,最后还是在Uvalive5920获得了一个AC,也算是不枉花费的时间了。
先上代码:#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mem(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef pair<int,int> pii;
const int mn=1e5+5;
int n,root;
int f[mn];
vector<int> g[mn],son[mn],leaf;
vector<pii> ans;
void dfs(int x,int fa){
f[x]=fa;
for(auto i:g[x]){
if (i==fa) continue;
dfs(i,x);
}
if (g[x].size()==1){
leaf.pb(x);
if (leaf.size()==3){
int u=leaf[1];
ans.pb(pii(leaf[0],x));
leaf.clear();
leaf.pb(u);
}
}
}
int main() {
while(~scanf("%d",&n)){
ans.clear();
for(int i=1;i<=n;i++) g[i].clear(),son[i].clear(),f[i]=0;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].pb(v);
g[v].pb(u);
}
if (n==2){
puts("1\n1 2");
}
for(int i=1;i<=n;i++){
if (g[i].size()>1) {
root=i;
break;
}
}
dfs(root,0);
if (leaf.size()==2) {
int u=leaf.back();
int v=*leaf.begin();
leaf.clear();
ans.pb(pii(u,v));
}
for(int i:leaf) ans.pb(pii(root,i));
leaf.clear();
//answer
printf("%d\n",ans.size());
for(auto i:ans) printf("%d %d\n",i.first,i.second);
}
return 0;
}我们先随便选一个度数大于2的点作为树根,然后从该树根延展出去。
显然,直接延展出去的每一条边都是一座桥。
为了去除连接每棵子树的根到更上层的桥,每棵子树应该预留下一个点(连上去),所以每棵子树都要留一个点或者两个点(三个点的时候就可以连接两个点了),这样一步步上去,搞搞好就ac辣。
相关文章推荐
- uva 1670 Kingdom Roadmap(图论构造题)
- Kingdom Roadmap UVA - 1670
- uvalive 4730王国kingdom(并查集+线段树)
- UVALive 4730 - Kingdom 树状数组区间修改单点查询
- ACM 图论 搜索 SPFA UVALive 5966 Blade and Sword
- UVALive 3713 浅谈2-SAT问题图论求解法
- uvalive 4730王国kingdom(并查集+线段树)
- UVaLive/LA 6804 Group of Strangers(图论)
- UVALive 5913 【NEERC 2011 K】 Kingdom Roadmap
- UVALive 4730 Kingdom(并查集加 线段树或树状数组)
- UVALive 4730 Kingdom 线段树+并查集
- UVALive 3211 (训练指南)图论例题9 2-sat+二分
- Let's Go Green UVALive - 6039题解 思维图论
- UVALive - 2957 Bring Them There(最大流 图论建模)
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)
- UVALive - 3621 Power Calculus
- uvaLive 6748 2D-Solar System
- UVALive - 2031 Dance Dance Revolution 三维dp
- UVa Live Archive 3971 & UVa 12124 & POJ 3497 - Assemble