LightOJ-1074 Extended Traffic

来源:互联网 发布:ubuntu amd双显卡切换 编辑:程序博客网 时间:2024/05/16 16:06

题目链接:https://vjudge.net/problem/LightOJ-1074

最短路问题,而且会有负环,需要把负环上的点都找出来,用spfa+dfs

用stack实现的spfa,比起用queue实现的快了有一倍(有负环情况下stack更快)

这题卡了很久,因为一个莫名的地方(代码里用注释标出来了),心累。。。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stack>using namespace std;const int N=200+20;const int inf=0x3f3f3f3f;int g[N][N];bool vis[N],r[N],g0[N][N];int d[N],c[N];int t,n,m,qu;void dfs(int u) //寻找负环并标记 {r[u]=true;for(int i=1;i<=n;i++)if(g0[u][i]&&!r[i])dfs(i);}int main(){scanf("%d",&t);int kase=0;while(t--){int num[N],cnt[N],a,b;memset(g,inf,sizeof(g));memset(g0,false,sizeof(g0));scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&num[i]);scanf("%d",&m);for(int i=0;i<m;i++){scanf("%d%d",&a,&b);g[a][b]=(num[b]-num[a])*(num[b]-num[a])*(num[b]-num[a]);g0[a][b]=true;}stack<int> q;q.push(1);memset(d,inf,sizeof(d));memset(vis,false,sizeof(vis));memset(r,false,sizeof(r));memset(cnt,0,sizeof(cnt));d[1]=0;vis[1]=true;cnt[1]=1;while(!q.empty())  //spfa {int u=q.top();q.pop();vis[u]=false;for(int i=1;i<=n;i++)if(!r[i]&&g0[u][i]&&d[i]>d[u]+g[u][i]) //必须先判断g0[u][i]是否联通???不然WA!!! {d[i]=d[u]+g[u][i];if(!vis[i]){q.push(i);vis[i]=true;cnt[i]++;if(cnt[i]>n)dfs(i);}}}scanf("%d",&qu);for(int i=0;i<qu;i++)scanf("%d",&c[i]);printf("Case %d:\n",++kase);for(int i=0;i<qu;i++){a=c[i];if(d[a]<3||d[a]>=inf||r[a]) printf("?\n");else printf("%d\n",d[a]);}}return 0;}


原创粉丝点击