hdu 5385 The path
2015-08-15 09:33
309 查看
HDU 5385 |
使用贪心法构造,因为保证有解,点2或n至少有一个直接与点1相连
上述结论可以用反证法证明。
假若2和n不直接与1相连,那么必存在点x直接与1相连,间接与2,n相连。这种情况下无论如何设置边权,都有d[x]<d[2]&&d[x]<d
,与已知矛盾
那么可以按照每次添加两头的点与1相连,记添加时间为1到该点的最短路,边添加边计算边权
然后不在最短路树上的边权都设为n即可,这样不会使最短路树发生变化
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn=100008; struct edge{ int v,i; }; int w[maxn]; vector<edge> g[maxn]; int uni[maxn],dis[maxn]; void solve(int n) { int v,idx,i; int left=2,right=n; dis[1]=0;int ti=0; while(left<right) { for(i=0;i<g[left].size();i++) { v=g[left][i].v; idx=g[left][i].i; if(uni[v]==1) { dis[left]=ti+1; w[idx]=dis[left]-dis[v]; uni[left++]=1; ti++; break; } } if(left>=right) break; for(i=0;i<g[right].size();i++) { v=g[right][i].v; idx=g[right][i].i; if(uni[v]==1) { dis[right]=ti+1; w[idx]=dis[right]-dis[v]; uni[right--]=1; ti++; break; } } } } int main() { int i,j,t,n,m,u,v; edge pp; //freopen("1006.in","r",stdin); // freopen("1011.txt","w",stdout); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) g[i].clear(); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); pp.i=i; pp.v=u; g[v].push_back(pp); } for(i=1;i<=n;i++) uni[i]=i; memset(w,-1,sizeof(w)); solve(n); for(i=1;i<=m;i++) { if(w[i]==-1) printf("%d\n",n); else printf("%d\n",w[i]); } } return 0; }
相关文章推荐
- 【cocos2d-js公文】十七、事件分发机制
- [笔记]unsigned int 转 char 数组uitoa 函数
- XCode新建Class时自动加前缀(class prefix 修改前缀)
- break和continue的区别以及标签label的使用
- Option使用和实现内幕源码揭秘之Scala学习笔记-22
- android launcher source code解析
- 图片通用上传文件类(处理水印,缩略图)
- C源码@数据结构与算法->二分查找树(Binary Search Tree)
- android adb详解
- 网络监听
- 如何读写二进制文件
- NYOJ 26 最长公共子序列
- java 回调 的来龙去脉
- Spark中文手册10:spark部署:提交应用程序及独立部署模式
- 将一个正整数分解质因数
- Backup and Recovery Strategies1
- 在JavaScript的jQuery库中操作AJAX的方法讲解
- 3.Python 条件if
- HTML表格标签
- hdu 4738 Caocao's Bridges