Description
给一棵树,每条边有非负权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, 1 <= K <= 1000000
Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)
Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1
Sample Input
4 3
0 1 1
1 2 2
1 3 4
Sample Output
2
转载自Navi_Awson的博客:http://www.cnblogs.com/NaVi-Awson/p/7560921.html
%%%Navi_Gayson大佬
有这个链接就行了,懒得写题解zyys
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Node 7 { 8 int next,to,dis; 9 }edge[400001]; 10 int num,head[200001],f[1000001],ans,k; 11 int size[200001],maxsize[200001],minsize,root,n; 12 bool vis[200001]; 13 int gi() 14 { 15 char ch=getchar(); 16 int x=0; 17 while (ch<‘0‘||ch>‘9‘) ch=getchar(); 18 while (ch>=‘0‘&&ch<=‘9‘) 19 { 20 x=x*10+ch-‘0‘; 21 ch=getchar(); 22 } 23 return x; 24 } 25 void add(int u,int v,int dis) 26 { 27 num++; 28 edge[num].next=head[u]; 29 head[u]=num; 30 edge[num].to=v; 31 edge[num].dis=dis; 32 } 33 void get_size(int x,int fa) 34 {int i; 35 size[x]=1; 36 maxsize[x]=0; 37 for (i=head[x];i;i=edge[i].next) 38 { 39 int v=edge[i].to; 40 if (vis[v]==0&&v!=fa) 41 { 42 get_size(v,x); 43 size[x]+=size[v]; 44 maxsize[x]=max(maxsize[x],size[v]); 45 } 46 } 47 } 48 void get_root(int r,int x,int fa) 49 {int i; 50 maxsize[x]=max(maxsize[x],size[r]-size[x]); 51 if (maxsize[x]<minsize) 52 {root=x;minsize=maxsize[x];} 53 for (i=head[x];i;i=edge[i].next) 54 { 55 int v=edge[i].to; 56 if (vis[v]==0&&v!=fa) 57 { 58 get_root(r,v,x); 59 } 60 } 61 } 62 void get_ans(int x,int fa,int cnt,int val) 63 {int i; 64 if (val>k) return; 65 if (f[k-val]||k==val) 66 ans=min(ans,f[k-val]+cnt); 67 for (i=head[x];i;i=edge[i].next) 68 { 69 int v=edge[i].to; 70 if (vis[v]==0&&v!=fa) 71 { 72 get_ans(v,x,cnt+1,val+edge[i].dis); 73 } 74 } 75 } 76 void get_update(int x,int fa,int cnt,int val) 77 {int i; 78 if (val>k) return; 79 if (f[k]==0) f[k]=cnt; 80 else f[k]=min(f[k],cnt); 81 for (i=head[x];i;i=edge[i].next) 82 { 83 int v=edge[i].to; 84 if (vis[v]==0&&v!=fa) 85 { 86 get_update(v,x,cnt+1,val+edge[i].dis); 87 } 88 } 89 } 90 void get_delete(int x,int fa,int cnt,int val) 91 {int i; 92 if (val>k) return; 93 f[val]=0; 94 for (i=head[x];i;i=edge[i].next) 95 { 96 int v=edge[i].to; 97 if (vis[v]==0&&v!=fa) 98 { 99 get_delete(v,x,cnt+1,val+edge[i].dis); 100 } 101 } 102 } 103 void solve(int x) 104 {int i; 105 minsize=2e9; 106 get_size(x,0); 107 get_root(x,x,0); 108 vis[root]=1; 109 for (i=head[root];i;i=edge[i].next) 110 { 111 int v=edge[i].to; 112 if (vis[v]==0) 113 { 114 get_ans(v,root,1,0); 115 get_update(v,root,1,0); 116 } 117 } 118 for (i=head[root];i;i=edge[i].next) 119 { 120 int v=edge[i].to; 121 if (vis[v]==0) 122 { 123 get_delete(v,root,1,0); 124 } 125 } 126 for (i=head[root];i;i=edge[i].next) 127 { 128 int v=edge[i].to; 129 if (vis[v]==0) 130 { 131 solve(v); 132 } 133 } 134 } 135 int main() 136 {int i,u,v,w; 137 cin>>n>>k; 138 for (i=1;i<=n-1;i++) 139 { 140 u=gi();v=gi();w=gi(); 141 u++;v++; 142 add(u,v,w); 143 add(v,u,w); 144 } 145 ans=2e9; 146 solve(1); 147 if (ans==2e9) cout<<-1; 148 else cout<<ans; 149 }
时间: 2024-10-29 02:45:38