Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 1 Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
Input
Output
Sample Input
5 1 1 2 1 3 1 1 1
Sample Output
3 2 3 4 4
Author
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int N=10010; struct node{ int to,cap; }a; vector<node> vt[N]; int n,dp[N],downf[N],downs[N],vis[N]; void DFS1(int u){ int flag1=-1,flag2=-1; if(downf[u]) return ; int len=vt[u].size(); if(len==0) return ; int MAX=-1; for(int i=0;i<len;i++){ //求最长距离, 由下往上递推 int v=vt[u][i].to; DFS1(v); //先dfs if(MAX<downf[v]+vt[u][i].cap){ //后处理 MAX=downf[v]+vt[u][i].cap; flag1=i; } } vis[u]=flag1; downf[u]=MAX; MAX=-1; for(int i=0;i<len;i++){ //求次长距离 int v=vt[u][i].to; if(i!=flag1 && MAX<downf[v]+vt[u][i].cap){ //i!=flag1 保证最远距离和次远距离不会重边 MAX=downf[v]+vt[u][i].cap; flag2=i; } } if(flag2!=-1) downs[u]=MAX; } void DFS2(int u){ //由上往下推 int len=vt[u].size(); if(len==0) return ; for(int i=0;i<len;i++){ int v=vt[u][i].to; if(i==vis[u]) //先处理 dp[v]=max(downs[u],dp[u])+vt[u][i].cap; //在父亲的最长路径上 else dp[v]=max(downf[u],dp[u])+vt[u][i].cap; //不在父亲的最长路径上 DFS2(v); //后dfs } } int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=0;i<=n;i++) vt[i].clear(); int u; for(int v=2;v<=n;v++){ scanf("%d%d",&u,&a.cap); a.to=v; vt[u].push_back(a); } memset(dp,0,sizeof(dp)); memset(downf,0,sizeof(downf)); memset(downs,0,sizeof(downs)); DFS1(1); DFS2(1); for(int i=1;i<=n;i++) printf("%d\n",max(downf[i],dp[i])); } return 0; }
另一种建图:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int VM=10010; struct Edge{ int to,nxt; int cap; }edge[VM<<1]; int n,cnt,head[VM]; int dp[VM],downf[VM],downs[VM],vis[VM]; void addedge(int cu,int cv,int cw){ edge[cnt].to=cv; edge[cnt].cap=cw; edge[cnt].nxt=head[cu]; head[cu]=cnt++; } void DFS1(int u){ int flag1=-1,flag2=-1; if(downf[u]) return ; if(head[u]==-1) return ; int MAX=-1; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; DFS1(v); if(MAX<downf[v]+edge[i].cap){ MAX=downf[v]+edge[i].cap; flag1=i; } } vis[u]=flag1; downf[u]=MAX; MAX=-1; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(i!=flag1 && MAX<downf[v]+edge[i].cap){ MAX=downf[v]+edge[i].cap; flag2=i; } } if(flag2!=-1) downs[u]=MAX; } void DFS2(int u){ if(head[u]==-1) return ; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(i==vis[u]) dp[v]=max(downs[u],dp[u])+edge[i].cap; else dp[v]=max(downf[u],dp[u])+edge[i].cap; DFS2(v); } } int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n)){ cnt=0; memset(head,-1,sizeof(head)); int u,w; for(int v=2;v<=n;v++){ scanf("%d%d",&u,&w); addedge(u,v,w); } memset(dp,0,sizeof(dp)); memset(downf,0,sizeof(downf)); memset(downs,0,sizeof(downs)); DFS1(1); DFS2(1); for(int i=1;i<=n;i++) printf("%d\n",max(downf[i],dp[i])); } return 0; }