您的位置:首页 > 其它

LightOJ 1074 Extended Traffic SPFA

2015-10-07 13:46 344 查看
题意:告诉n个点,每个点都有一个权值,A 到 B的时间等于 (val[b]-val[a])^3  都是单向边,可能存在负环,Q次询问,问从1到询问点的最短路,如果不可达或者点在负环上或者小于3,那么就输出? 否则输出最短路径值

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#define INF 1<<30
using namespace std;

int a[222];
int vis[222],head[222];
int dis[222];
int cnt;
int num[222];
int useq[222];
queue<int>q;

struct Node
{
int nt,v,w;
}f[22222];

void add(int u,int v,int w)
{
f[cnt].v=v;
f[cnt].w=w;
f[cnt].nt=head[u];
head[u]=cnt++;
}

void dfs(int k)//标记负环中的点
{
num[k]=1;
for(int i=head[k];i!=-1;i=f[i].nt)
{
if(num[f[i].v]==0)
{
dfs(f[i].v);
}
}
}

void spfa(int st,int n)
{
dis[1]=0;
vis[1]=1;
q.push(1);
useq[1]++;

while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
// if(num[x]) continue;

for(int i=head[x];i!=-1;i=f[i].nt)
{
if(num[f[i].v]) continue;
if(dis[f[i].v]>dis[x]+f[i].w)
{
dis[f[i].v]=dis[x]+f[i].w;
if(vis[f[i].v]==0)
{
vis[f[i].v]=1;
q.push(f[i].v);
useq[f[i].v]++;

if(useq[f[i].v]>=n)//如果存在负环则开始标记
dfs(f[i].v);
}
}
}
}

}

int main()
{
int T;
scanf("%d",&T);
int n,m,q;
for(int ca=1;ca<=T;ca++)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);

scanf("%d",&m);
cnt=0;

for(int i=0;i<=n;i++)
{
head[i]=-1;
dis[i]=INF;
vis[i]=0;
num[i]=0;
useq[i]=0;
}
int u,v;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
add(u,v,(a[v]-a[u])*(a[v]-a[u])*(a[v]-a[u]));
}

spfa(1,n);
printf("Case %d:\n",ca);
scanf("%d",&q);
for(int i=0;i<q;i++)
{
scanf("%d",&u);
if(num[u] || dis[u]<3 || dis[u]==INF)
puts("?");
else
printf("%d\n",dis[u]);
}
}

return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: