noip2018 赛道修建
http://210.33.19.103/contest/1050/problem/3
http://210.33.19.103/contest/1054/problem/3
multiset版本(TLE)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 #define int ll 15 struct E 16 { 17 int to,nxt,d; 18 }e[200100]; 19 int f1[100100],ne; 20 int n,m; 21 int d1[100100],d2[100100];//d1表示最大产生答案,d2表示剩下的到根最长路径 22 int x; 23 multiset<int> s; 24 multiset<int>::iterator i1; 25 void dfs(int u,int fa) 26 { 27 d1[u]=d2[u]=0; 28 int v; 29 for(int k=f1[u];k;k=e[k].nxt) 30 { 31 v=e[k].to; 32 if(v!=fa) 33 { 34 dfs(v,u); 35 d1[u]+=d1[v]; 36 } 37 } 38 int num=0,t1,max1=0; 39 s.clear(); 40 for(int k=f1[u];k;k=e[k].nxt) 41 if(e[k].to!=fa) 42 { 43 t1=d2[e[k].to]+e[k].d; 44 if(t1>=x) {++num;} 45 else s.insert(t1); 46 } 47 while(!s.empty()) 48 { 49 i1=s.begin(); 50 t1=*i1;s.erase(i1); 51 i1=s.lower_bound(x-t1); 52 if(i1==s.end()) {max1=max(max1,t1);continue;} 53 s.erase(i1); 54 ++num; 55 } 56 d1[u]+=num; 57 d2[u]=max1; 58 if(!s.empty()) d2[u]=max(d2[u],*s.rbegin()); 59 } 60 bool judge() 61 { 62 dfs(1,0); 63 /* 64 printf("1t%d\n",x); 65 for(int i=1;i<=n;++i) 66 printf("%d ",d1[i]); 67 puts(""); 68 */ 69 return d1[1]>=m; 70 } 71 signed main() 72 { 73 int i,x,y,z; 74 scanf("%lld%lld",&n,&m); 75 for(i=1;i<n;++i) 76 { 77 scanf("%lld%lld%lld",&x,&y,&z); 78 e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z; 79 e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;e[ne].d=z; 80 } 81 int l=1,r=500000000,mid; 82 while(l!=r) 83 { 84 mid=l+((r-l)>>1); 85 if(::x=mid+1,judge()) l=mid+1; 86 else r=mid; 87 } 88 printf("%lld\n",l); 89 return 0; 90 }
可AC版本
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 struct E 15 { 16 int to,nxt,d; 17 }e[200100]; 18 int f1[100100],ne; 19 int n,m; 20 int d1[100100],d2[100100];//d1表示最大产生答案,d2表示剩下的到根最长路径 21 int x; 22 int s[100100]; 23 int fa1[100100]; 24 int find(int x){return x==fa1[x]?x:fa1[x]=find(fa1[x]);} 25 void dfs(int u,int fa) 26 { 27 d1[u]=d2[u]=0; 28 int v; 29 for(int k=f1[u];k;k=e[k].nxt) 30 { 31 v=e[k].to; 32 if(v!=fa) 33 { 34 dfs(v,u); 35 d1[u]+=d1[v]; 36 } 37 } 38 int num=0,t1,t2,max1=0,i; 39 s[0]=0; 40 for(int k=f1[u];k;k=e[k].nxt) 41 if(e[k].to!=fa) 42 { 43 t1=d2[e[k].to]+e[k].d; 44 if(t1>=x) ++num; 45 else s[++s[0]]=t1; 46 } 47 sort(s+1,s+s[0]+1); 48 for(i=1;i<=s[0]+1;++i) fa1[i]=i; 49 while(1) 50 { 51 t1=find(1); 52 if(t1>s[0]) break; 53 fa1[t1]=find(t1+1); 54 t2=lower_bound(s+1,s+s[0]+1,x-s[t1])-s; 55 t2=find(t2); 56 if(t2>s[0]) {max1=max(max1,s[t1]);continue;} 57 fa1[t2]=find(t2+1); 58 ++num; 59 } 60 d1[u]+=num; 61 d2[u]=max1; 62 for(i=1;i<=s[0];++i) 63 if(fa1[i]==i) 64 d2[u]=max(d2[u],s[i]); 65 } 66 bool judge() 67 { 68 dfs(1,0); 69 return d1[1]>=m; 70 } 71 signed main() 72 { 73 int i,x,y,z; 74 scanf("%d%d",&n,&m); 75 for(i=1;i<n;++i) 76 { 77 scanf("%d%d%d",&x,&y,&z); 78 e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z; 79 e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;e[ne].d=z; 80 } 81 int l=1,r=500000000,mid; 82 while(l!=r) 83 { 84 mid=l+((r-l)>>1); 85 if(::x=mid+1,judge()) l=mid+1; 86 else r=mid; 87 } 88 printf("%d\n",l); 89 return 0; 90 }