您的位置:首页 > 其它

CF 241E flights 最短路,重复迭代直到稳定 难度:3

2015-03-16 14:50 232 查看
http://codeforces.com/problemset/problem/241/E

首先检测哪些点会出现在从起点到终点的路上,可以用dfs或者迭代,

然后,对于所有的边,设f为边起点,t为边终点,dp[i]为从起点出发到i点所必须花费的时间,则当dp[t]>dp[f]+2,也就是超出限制时,把dp[t]限制到dp[f]+2处,对于dp[f]>dp[t]+1,限制dp[f]到dp[t]+1处

因为这个图没有圈,所以如果存在满足题意的边权方案,那么每次使得一个点的dp值满足要求,n次之后一定全部满足要求,不再发生改动,如果不存在满足题意的边权方案,就会不断发生震荡,此时及时停止循环输出No即可

注意不在起点到终点路上的边全都为1

#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e3+2;
const int maxm=5e3+2;
const int inf=0x3fffffff;
int n,m;
int vis[maxn];
int e[maxm][2];
int dp[maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)scanf("%d%d",e[i],e[i]+1);
vis[1]=1;vis
=2;
bool fl=true;
while(fl){
fl=false;
for(int i=0;i<m;i++){
int f=e[i][0],t=e[i][1];
if((vis[f]&1)&&(vis[t]&1)==0){
vis[t]|=1;fl=true;
}
if((vis[t]&2)&&(vis[f]&2)==0){
vis[f]|=2;fl=true;
}
}
}
fl=true;
int cnt=0;
while(fl){
fl=false;
cnt++;
for(int i=0;i<m;i++){
int f=e[i][0],t=e[i][1];
if(vis[f]==3&&vis[t]==3){
if(dp[t]>dp[f]+2){
dp[t]=dp[f]+2;
fl=true;
}
if(dp[f]>dp[t]-1){
dp[f]=dp[t]-1;
fl=true;
}
}
}
if(cnt>n&&fl){puts("No");return 0;}
}
puts("Yes");
for(int i=0;i<m;i++){
int f=e[i][0],t=e[i][1];
if(vis[f]==3&&vis[t]==3)printf("%d\n",dp[t]-dp[f]);
else puts("1");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: