bzoj 2599: [IOI2011]Race
2599: [IOI2011]Race
Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 4732 Solved: 1385
[Submit][Status][Discuss]
Description
给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000
Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)
Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1
Sample Input
4 3
0 1 1
1 2 2
1 3 4
0 1 1
1 2 2
1 3 4
Sample Output
2
HINT
2018.1.3新加数据一组,未重测
#include<iostream> #include<cstdio> #include<cstring> #define maxn 200010 #define INF 1000000000 using namespace std; int n,m,num,root,sum,ans; int son[maxn],head[maxn],dis[maxn],d[maxn],f[maxn],vis[maxn],t[maxn*5]; struct node{int to,pre,v;}e[maxn*2]; void Insert(int from,int to,int v){ e[++num].to=to; e[num].v=v; e[num].pre=head[from]; head[from]=num; } void getroot(int x,int father){ son[x]=1;f[x]=0; for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(to==father||vis[to])continue; getroot(to,x); son[x]+=son[to]; f[x]=max(f[x],son[to]); } f[x]=max(f[x],sum-son[x]); if(f[x]<f[root])root=x; } void cal(int x,int father){ if(dis[x]<=m)ans=min(ans,d[x]+t[m-dis[x]]); for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(to==father||vis[to])continue; d[to]=d[x]+1; dis[to]=dis[x]+e[i].v; cal(to,x); } } void add(int x,int father,int flag){ if(dis[x]<=m){ if(flag)t[dis[x]]=min(d[x],t[dis[x]]); else t[dis[x]]=INF; } for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(to==father||vis[to])continue; add(to,x,flag); } } void solve(int x){ vis[x]=1;t[0]=0; for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(vis[to])continue; d[to]=1;dis[to]=e[i].v; cal(to,0); add(to,0,1); } for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(!vis[to])add(to,0,0); } for(int i=head[x];i;i=e[i].pre){ int to=e[i].to; if(vis[to])continue; sum=son[to];root=0; getroot(to,0); solve(root); } } int main(){ freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)t[i]=n; int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); x++;y++; Insert(x,y,z);Insert(y,x,z); } sum=ans=f[0]=n; getroot(1,0); solve(root); if(ans==n)puts("-1"); else printf("%d\n",ans); return 0; }