lightoj 1074【spfa判负环】
题意:
给你一幅图,dis(u->v)的权值就是(w[v]-w[u])*(w[v]-w[u])*(w[v]-w[u]),所以有可能是负的,给你n个询问,给出最短路,长度<3或者不可达输出"?";
思路:
spfa判个负环就好了;
但是。。。。没有考虑与负环相连的所有都是会越来越来,所以每次有负环,要搜一下,把整块拿掉
100
6
11 12 9 8 7 10
6
5 6
1 2
2 5
3 1
5 4
4 3
给你一幅图,dis(u->v)的权值就是(w[v]-w[u])*(w[v]-w[u])*(w[v]-w[u]),所以有可能是负的,给你n个询问,给出最短路,长度<3或者不可达输出"?";
思路:
spfa判个负环就好了;
但是。。。。没有考虑与负环相连的所有都是会越来越来,所以每次有负环,要搜一下,把整块拿掉
100
6
11 12 9 8 7 10
6
5 6
1 2
2 5
3 1
5 4
4 3
100
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int>PII; const double eps=1e-5; const double pi=acos(-1.0); //const int mod=1e9+7; const int INF=0x3f3f3f3f; const int N=4e4+10; struct Edge{ int w; int to; int next; }; Edge q[N]; int head[N],tol; int dis[210],n; int w[210],num[210]; bool vis[210]; bool in[210]; void dfs(int u) { in[u]=1; for(int i=head[u];i!=-1;i=q[i].next) { int to=q[i].to; if(!in[to]) dfs(to); } } queue<int>que; void spfa() { while(!que.empty()) que.pop(); for(int i=1;i<=n;i++) { vis[i]=false; num[i]=0; dis[i]=INF; } vis[1]=true; dis[1]=0; num[1]++; que.push(1); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=false; for(int i=head[u];i!=-1;i=q[i].next) { int v=q[i].to; if(in[v]) continue; if(dis[v]>dis[u]+q[i].w) { dis[v]=dis[u]+q[i].w; if(!vis[v]) { vis[v]=true; num[v]++; if(num[v]>n) { dfs(v); continue; } que.push(v); } } } } } void add(int u,int v,int w) { q[tol].w=w; q[tol].to=v; q[tol].next=head[u]; head[u]=tol++; } void init() { tol=0; memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); } int main() { int m,Q; int T,cas=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&w[i]); init(); scanf("%d",&m); while(m--) { int u,v; scanf("%d%d",&u,&v); add(u,v,(w[v]-w[u])*(w[v]-w[u])*(w[v]-w[u])); } spfa(); printf("Case %d:\n",cas++); scanf("%d",&Q); while(Q--) { int u; scanf("%d",&u); if(in[u]||dis[u]==INF||dis[u]<3) puts("?"); else printf("%d\n",dis[u]); } } return 0; }