传球接力
来源:互联网 发布:c websocket java 编辑:程序博客网 时间:2024/04/30 10:20
50%的做法:枚举每一个点,一直走到尽头,记录长度,更新答案。
像这样的有n条边,n个点,每个点都有一条出边的点一定存在环。这样的图叫做 环加外向树。
那么对于这道题的满分做法,先求出每颗树的叶子到树根的最长路径记为f[i],再找出环,然后每次枚举环上的点x,(环的长度len),用len-d[x]+f[to[x]]来更新答案就可以了。
求环的时候,有很多种方法,然而用dfs是超时的。
我们可以先求f数组,在求f数组的时候,先找出入度为零的点,更新它的邻接点的f,然后将这个点删去(将它邻接点的入度减 1)就可以了。这样我们在找环的时候,入度>0的点就是在环中的点。这样是一个较优的做法。
先贴上50分代码
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define LL long long#define M 500009using namespace std;int n,to[M],d[M];LL len;bool f[M];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&to[i],&d[i]); for(int i=1;i<=n;i++) { memset(f,0,sizeof(f)); int x=i;LL l=0; while(to[x]&&!f[to[x]]&&d[x]>=0) { l+=d[x]; f[x]=1; x=to[x]; } len=max(len,l); } printf("%lld",len); return 0;}
60分的dfs找环代码
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define LL long long#define M 500009using namespace std;int n,d[M],to[M],f[M],st[M],top,pos[M];int color[M],color_num;int from[M];vector <int> A[M]; LL ans,len[M];bool vis[M];void dfs(int x){ vis[x]=1;st[++top]=x,pos[x]=top; if(color[to[x]]) return; if(!vis[to[x]]) vis[to[x]]=1,dfs(to[x]); else{ ++color_num; for(int i=pos[to[x]];i<=top;i++) { color[st[i]]=color_num; A[color_num].push_back(st[i]); len[color_num]+=d[st[i]]; } } }int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&to[i],&d[i]); from[to[i]]++; } for(int i=1;i<=n;i++) { if(!from[i]&&!vis[i]) { memset(vis,0,sizeof(vis)); dfs(i); } } for(int i=1;i<=n;i++) { if(!from[i]) { int x=i; while(1) { f[to[x]]=max(f[to[x]],f[x]+d[x]); if(color[to[x]]) break; x=to[x]; } } } for(int i=1;i<=color_num;i++) { for(int j=0;j<A[i].size();j++) { ans=max(ans,f[to[A[i][j]]]+len[i]-d[A[i][j]]); } } printf("%lld",ans); return 0;}
100分代码
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define LL long long#define M 500009using namespace std;int n,d[M],to[M],f[M],from[M],q[M],L,R;LL ans,len;bool vis[M];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&to[i],&d[i]); from[to[i]]++; } for(int i=1;i<=n;i++) if(from[i]==0) q[++R]=i; while(L<R) { int x=q[++L]; f[to[x]]=max(f[to[x]],f[x]+d[x]); if(--from[to[x]]==0) q[++R]=to[x]; } for(int i=1;i<=n;i++) { if(!vis[i]&&from[i]>0) { int x=i; R=0; len=0; while(1) { len+=d[x]; vis[x]=1; q[++R]=x; x=to[x]; if(x==i) break; } for(int j=1;j<=R;j++) { LL l=len-d[q[j]]+f[to[q[j]]]; ans=max(l,ans); } } } printf("%lld",ans); return 0;}
阅读全文
1 0
- 传球接力
- 传球接力
- 传球接力
- 接力
- 幸福接力幸福接力
- 幸福接力
- 古诗接力
- 古诗接力
- 古诗接力
- 古诗接力
- 奶牛接力
- 测试接力
- 接力break
- 传球游戏
- 传球游戏
- 传球游戏
- 传球游戏
- 传球问题
- 70. Climbing Stairs
- java-----建立对象时代码执行顺序
- 搭建伪分布式集群
- 习题 3-8 循环小数 Repeating Decimals UVa 202
- Oracle VM VirtualBox的使用
- 传球接力
- cut --- 文本剪切工具
- 算法模板之拓扑排序
- Xampp-服务器根目录路径设置
- C++ 指针和引用的区别
- 【名师大讲坛】叶俊受《金刚经》的启发创造“名非论”-火锅智烩节目组根据视频文字整理
- servlet学习笔记(三)-Context
- win7 64位 无法解析的外部符号:posix_memalign vs2015 itk4.11
- bzoj 4827 礼物(fft)