COGS2109 http://cogs.pro:8080/cogs/problem/problem.php?pid=2109
洛谷交上去一直CE啊好绝望
COGS交了90分,一个点WA,一个点TLE嘤嘤嘤
恕我是在找不出来错误了
思路
先算LCA,深度,父节点什么的
二分答案,然后我们贪心的验证:
先找出所有应该改小的路径,记录个数和最大值,并差分地标记在在树上
随后DFS,找出所有应改小的路径都经过的边,即查询差分的值等于前面记录的个数的边
如果没找到,说明答案太苛刻了,放松一点
如果找到了,决定去掉其中权最大的那条边
如果这条边能让最长的路径合法,说明其他路径皆能合法,收紧答案
否则放松答案
然后完了,然而并不知道哪里错了
卡常好恶心
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 300010 4 inline bool isitdigit(char c){return c<='9'&&c>='0';} 5 inline int maintain(int &a,int b){ return a>b?a:a=b;} 6 inline int read() 7 { 8 register int s;register char c; 9 while(!isitdigit(c=getchar())); 10 for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0'); 11 return s; 12 } 13 int findset[N]; 14 inline int find(int x){return x==findset[x]? x:findset[x]=find(findset[x]);} 15 inline int merge(int a,int b){return find(a)==find(b)?0:findset[findset[a]]=findset[b];} 16 int n,m; 17 int head[N],to[N*2],next[N*2],value[N*2],tot; 18 struct ask{ 19 int v,u,lca,dis; 20 }road[N]; 21 int u[2*N],v[2*N],linking[2*N],enter[N],dis[N],deep[N],lca[2*N],cnt,maxdis,mark[N],father[N],maxside; 22 inline void add(int f,int t,int v){to[++tot]=t;value[tot]=v;next[tot]=head[f];head[f]=tot;} 23 inline void conect(int f,int t){u[++cnt]=f;v[cnt]=t;linking[cnt]=enter[f];enter[f]=cnt;} 24 void tarjan(int i,int f,int d) 25 { 26 father[i]=f; 27 deep[i]=d; 28 for(register int j=head[i];j;j=next[j]) if(to[j]!=f) 29 { 30 tarjan(to[j],i,d+value[j]); 31 merge(to[j],i); 32 } 33 for(register int j=enter[i];j;j=linking[j]) if(~deep[v[j]]) lca[j]=find(v[j]); 34 } 35 int dfs(int i,int f,int v) 36 { 37 int d=mark[i]; 38 for(register int j=head[i];j;j=next[j]) if(to[j]!=f) d+=dfs(to[j],i,value[j]); 39 if(d==cnt) maintain(maxside,v); 40 return d; 41 } 42 43 inline bool cal(int ans) 44 { 45 cnt=maxdis=maxside=0; 46 memset(mark,0,sizeof(mark)); 47 for(register int i=1;i<=m;++i) if(road[i].dis>ans) 48 { 49 cnt++,maintain(maxdis,road[i].dis); 50 mark[father[road[i].lca]]-=2; 51 mark[road[i].u]++,mark[road[i].v]++; 52 } 53 54 dfs(1,0,0); 55 return maxdis-maxside<=ans; 56 } 57 58 59 int main() 60 { 61 freopen("transport.in","r",stdin); 62 freopen("transport.out","w",stdout); 63 memset(deep,0xff,sizeof(deep)); 64 n=read(),m=read(); 65 for(register int i=1;i<=n;++i) findset[i]=i; 66 for(register int i=1;i<n;++i) 67 { 68 int f=read();int t=read();int v=read(); 69 add(f,t,v),add(t,f,v); 70 } 71 for(register int i=1;i<=m;++i) 72 { 73 int f=read();int t=read(); 74 conect(f,t),conect(t,f); 75 } 76 tarjan(1,0,0); 77 for(register int i=2;i<=cnt;i+=2) lca[i]==0? lca[i]=lca[i-1]:lca[i]; 78 for(register int i=2;i<=cnt;i+=2) road[i>>1]=(ask){v[i],u[i],lca[i],deep[u[i]]+deep[v[i]]-(deep[lca[i]]<<1)}; 79 int l=0,r=1000*n; 80 while(l<r) 81 { 82 int mid=(l+r)>>1; 83 if(cal(mid))r=mid; 84 else l=mid+1; 85 } 86 printf("%d",l); 87 return 0; 88 }