SPOJ 18469 UOFTCG
来源:互联网 发布:mac百度云盘怎么卸载 编辑:程序博客网 时间:2024/06/11 19:55
Description
先在要个n个人安排座位,要求是一个人两边不能有不认识的人,两个不认识的人之间必须用一个空座隔开,问最少需要多少座位好
Input
第一行一整数T表示用例组数,每组用例首先输入两整数n和m表示人数和关系数,之后m行每行两个整数u和v表示u和v认识,保证任意k个人之间最多有k-1对人认识(T<=50,n<=1e6)
Output
输出一整数表示最少需要的座位数量
Sample Input
1
6 5
1 2
1 3
1 4
4 5
4 6
Sample Output
7
Solution
贪心,问题其实是把一片森林分成最少的链,对于森林中的每棵树贪心的从底层开始剖分,如果一个节点超过一个可用儿子,那么只能是两个儿子节点(或者说两个儿子节点为祖先的两条链)和这个点组成一个链,其他儿子孤立作为单点链;如果一个节点只有一个可用儿子,那么该节点先和父亲节点连上看往上是否能和其他祖先节点连起来(注意该点如果是根节点那么就没有其他祖先节点连了,所以直接成一条链)
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 111111int T,n,m,vis[maxn],ans,root;vector<int>g[maxn];int dfs(int u){ vis[u]=1; int num=0; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(vis[v])continue; num+=dfs(v); } if(num>=2) { ans+=num-1; return 0; } if(u==root)ans++; return 1;}int main(){ scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)g[i].clear(); while(m--) { int u,v; scanf("%d%d",&u,&v); g[u].push_back(v),g[v].push_back(u); } memset(vis,0,sizeof(vis)); ans=0; for(int i=1;i<=n;i++) if(!vis[i])root=i,dfs(i); printf("%d\n",n+ans-1); } return 0;}
0 0
- SPOJ 18469 UOFTCG
- [SPOJ UOFTCG Office Mates]
- SPOJ - UOFTCG(树的路径覆盖,好题)
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- 链式前向星,前向星,vector模拟链表
- spark.mllib源码阅读-分类算法4-DecisionTree
- C语言编写FIR数字低通滤波器
- Navicat导出MySQL的数据字典
- 【精品】对同步的理解,进而理解lock与synchronized。
- SPOJ 18469 UOFTCG
- 第三方支付
- Delete Node in a Linked List
- 输入任意一年,判断该年是否是闰年
- nodejs前端框架 express4以及express-generator构建前端项目
- 喷水装置(二)
- 实现Runnable接口的线程
- VI判断两个数的大小
- 237. Delete Node in a Linked List