【AMPPZ2014】【BZOJ4151】The Cave
2015-12-06 16:54
423 查看
Description
给定一棵有n个节点的树,相邻两点之间的距离为1。
请找到一个点x,使其满足所有m条限制,其中第i条限制为dist(x,a[i])+dist(x,b[i])<=d[i]。
Input
第一行包含一个正整数t(1<=t<=1000),表示数据组数。
对于每组数据,第一行包含两个正整数n,m(2<=n,m<=300000),表示点数、限制数。
接下来n-1行,每行两个正整数x,y(1<=x,y<=n),表示树上的一条边。
接下来m行,每行三个正整数a[i],b[i],di,描述一条限制。
输入数据保证所有n之和不超过300000,所有m之和也不超过300000。
Output
输出t行。第i行输出第i组数据的答案,如果无解输出NIE,否则输出TAK,
然后输出x,如有多组解,输出任意一组。
Sample Input
2
5 3
1 2
2 3
2 4
3 5
1 4 2
5 5 5
3 2 1
3 2
1 2
2 3
1 1 2
3 3 1
Sample Output
TAK 2
NIE
HINT
Source
鸣谢Claris上传
这题我真不会做了..
Claris的AMPPZ2014
给定一棵有n个节点的树,相邻两点之间的距离为1。
请找到一个点x,使其满足所有m条限制,其中第i条限制为dist(x,a[i])+dist(x,b[i])<=d[i]。
Input
第一行包含一个正整数t(1<=t<=1000),表示数据组数。
对于每组数据,第一行包含两个正整数n,m(2<=n,m<=300000),表示点数、限制数。
接下来n-1行,每行两个正整数x,y(1<=x,y<=n),表示树上的一条边。
接下来m行,每行三个正整数a[i],b[i],di,描述一条限制。
输入数据保证所有n之和不超过300000,所有m之和也不超过300000。
Output
输出t行。第i行输出第i组数据的答案,如果无解输出NIE,否则输出TAK,
然后输出x,如有多组解,输出任意一组。
Sample Input
2
5 3
1 2
2 3
2 4
3 5
1 4 2
5 5 5
3 2 1
3 2
1 2
2 3
1 1 2
3 3 1
Sample Output
TAK 2
NIE
HINT
Source
鸣谢Claris上传
这题我真不会做了..
Claris的AMPPZ2014
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 300010 #define GET (ch>='0'&&ch<='9') using namespace std; int T,n,m,top; int a[MAXN],b[MAXN],d[MAXN],dis[3][MAXN]; struct edge { int to; edge *next; }e[MAXN<<1],*prev[MAXN]; void insert(int u,int v) {e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top];} void in(int &x) { char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar(); } void dfs(int x,int f,int d,int now) { dis[now][x]=d++; for (edge *i=prev[x];i;i=i->next) if (i->to!=f) dfs(i->to,x,d,now); } int main() { in(T);int u,v,maxn; while (T--) { top=0;for (int i=1;i<=n;i++) prev[i]=NULL; in(n);in(m); for (int i=1;i<n;i++) in(u),in(v),insert(u,v),insert(v,u); for (int i=1;i<=m;i++) in(a[i]),in(b[i]),in(d[i]); dfs(1,0,0,0);u=0;maxn=0; for (int i=1;i<=m;i++) { v=dis[0][a[i]]+dis[0][b[i]]-d[i]; if (u==0||v>maxn) u=i,maxn=v; } dfs(a[u],0,0,1);dfs(b[u],0,0,2);v=0; for (int i=1;i<=n;i++) if (dis[1][i]+dis[2][i]<=d[u]&&(!v||dis[0][i]<maxn)) v=i,maxn=dis[0][i]; if (!v) {puts("NIE");continue;} dfs(v,0,0,0); for (int i=1;i<=m;i++) if (dis[0][a[i]]+dis[0][b[i]]>d[i]) {v=0;break;} if (v) printf("TAK %d\n",v);else puts("NIE"); } }
相关文章推荐
- windows linux Git使用总结
- 信息安全系统设计基础实验五 20135211&20135216
- Date对象
- linux笔记 第九天 软raid、bash循环进阶、lvm详解、压缩和归档工具
- 20151206 重新搭建oracle11g环境碰到的困难 Linux篇
- android studio使用异常解决记录
- 信息安全系统设计基础实验四 20135211&20135216
- 数据注解特性--Table
- 动态规划算法(后附常见动态规划为题及Java代码实现)
- python 在cmd下面报错
- 4000 Lighter ViewControllers
- CentOS6.7系统文本安装
- 【android】seekbar 样式自定义
- 封装
- http响应状态码
- ==== 如何写自己的回调函数
- 图像融合
- windows平台中配置nginx+php环境
- hdu 2108 Shape of HDU 计算几何(向量的叉积)
- 朴素贝叶斯算法(NB)