(spfa) Wormholes (P3259)

来源:互联网 发布:单片机 二维码打印 编辑:程序博客网 时间:2024/06/07 15:25

题意:求一个图中是否有负环


网址:http://poj.org/problem?id=3259


这里有两种比较合适的解法。


首先给出floyd算法(自己暂定先这么叫)的吧。

#include<iostream>#include<queue>using namespace std;struct pp{int from,to,v;}p[15004];int dis[1001];int n,t,w,m;bool floyd(){int i,j,k;memset(dis,0,sizeof(dis));for (i=0;i<n;i++){bool isok=false;for (j=0;j<w;j++) if (dis[p[j].to] > dis[p[j].from]+p[j].v)dis[p[j].to]=dis[p[j].from]+p[j].v, isok=true;if (!isok)return false;}return true;}int main(){freopen("in.txt","r",stdin);int i,j,k;cin>>t;while (t--){cin>>n>>w>>m;for (i=0;i<w;i++){cin>>p[i].from>>p[i].to>>p[i].v;p[i+w]=p[i];swap(p[i+w].from,p[i+w].to);}w<<=1;while (m--){cin>>p[w].from>>p[w].to>>k;p[w++].v=-k;}if (floyd())cout<<"YES"<<endl;elsecout<<"NO"<<endl;}}


第二种spfa待更新,这里就得注意重边的情况 


#include<iostream>#include<queue>#include<vector>using namespace std;#define inf 1000000000struct my{int id,v;};vector<my> v[1111];int n,m,w;int b[1111];int dis[1111];int vis[1111];int map[1001][1001];int main(){freopen("in","r",stdin);int i,j,k;int t;my cur;cin>>t;deque<int> q; while (t--){cin>>n>>m>>w;for (i=1;i<=n;i++)v[i].clear(),dis[i]=inf,b[i]=0,vis[i]=0;for (i=1;i<=n;i++)for (j=1;j<=n;j++)map[i][j]=inf;while (m--){cin>>i>>j>>k;map[i][j]=map[j][i]=min(k,map[i][j]); //这里有重边 }while (w--){cin>>i>>j>>k;map[i][j]=-k;}for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (map[i][j]!=inf)cur.id=j,cur.v=map[i][j],v[i].push_back(cur);bool isok=false;q.clear();q.push_back(1);dis[1]=0;b[1]++;while (!q.empty()){int d=q.front();q.pop_front();vis[d]=0;if (b[d]>=n){isok=true;break;}for (i=0;i<v[d].size();i++) if (dis[v[d][i].id] > dis[d]+v[d][i].v){int next=v[d][i].id;dis[next] = dis[d]+v[d][i].v;    //这里很重要,虽然不能入队,但是要更新。 if (!vis[next]){vis[next]=1;dis[next]=dis[d]+v[d][i].v;q.push_back(next);b[next]++;}}}if (isok)puts("YES");elseputs("NO");}return 0;}












0 0
原创粉丝点击