用前向星链表速度很快
SPFA有时会被恶意数据卡掉,如果没有负边权的话还是建议使用Dijkstra
标准:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define LL long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 2147483647 #define N 500000+50 int dis[N],vis[N],head[N],n,m,s,pos,k,L,R,ans; struct Edge { int next,v,to; }edge[N]; void addedge(int a,int b,int c) { edge[++pos]=Edge{head[a],c,b}; head[a]=pos; } void spfa(int s) { queue<int>q; rep(i,1,n) dis[i]=inf,vis[i]=0; q.push(s); dis[s]=0; vis[s]=1; while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].v) { dis[v]=dis[u]+edge[i].v; if(vis[v]==0) { vis[v]=1; q.push(v); } } } } }
判断负权环:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f #define N 1000+5 struct node { int to,nex,v; }edge[N]; int pos=0; int head[N]; void add(int a,int b,int c) { edge[++pos].nex=head[a]; head[a]=pos; edge[pos].v=c; edge[pos].to=b; } int n,m; int vis[N]; int dis[N]; int cnt[N]; bool spfa() { queue<int>q; CLR(vis,0); CLR(dis,0x3f); CLR(cnt,0); q.push(n+1); dis[n+1]=0; vis[n+1]=1;//n+1为起始点 cnt[n+1]=1; while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=head[u];i;i=edge[i].nex) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].v) { dis[v]=dis[u]+edge[i].v; if(!vis[v]) { cnt[v]++; if(cnt[v]>n)return 0; q.push(v); vis[v]=1; } } } } return 1; } int main() { while(RI(n),n) { RI(m); CLR(head,0); pos=0; string str; int a,b,k; while(m--) { RII(a,b);cin>>str;RI(k); if(str=="gt") add(a+b,a-1,-k-1); else add(a-1,a+b,k-1); } rep(i,1,n) add(n+1,i,0);//这里ab顺序反了也会错 if(spfa()) printf("lamentable kingdom "); else printf("successful conspiracy "); } return 0; }
bellman判环
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
bool bellman_ford(int n, int m) { //因为是求存不存在负权回路,那么只要初始化为0,更新n遍之后,如果还能再更新,那么就存在 for(int i=1; i<=n; ++i) dist[i] = 0; for(int i=1; i<=n; ++i)//n+1个点,所以要更新n遍 { for(int j=0; j<m; ++j) { Edge &e = es[j]; //因为图是不连通的,所以如果置为INF的时候,不能在这里加这个条件 if( dist[e.to] > dist[e.from] + e.dist) dist[e.to] = dist[e.from] + e.dist; } } for(int j=0; j<m; ++j) { Edge &e = es[j]; if(dist[e.to] > dist[e.from] + e.dist) return false; } return true; }