基础最短路六 POJ3259

来源:互联网 发布:天猫的网络教育真的吗 编辑:程序博客网 时间:2024/05/25 23:57


POJ3259:http://poj.org/problem?id=3259

n为500,m为2500


题目大意:有一个人在n个点之间走来走去。n个点之间有双向的道路,也有单向的 可以回到几秒前的虫洞。

 

            问: 存不存在一种走法,走来走去走来走去,走回到起点的时候,时间刚好在自己出发以前?

     

又是一个Spfa寻找负环问题!

输入虫洞的时候,权改为负数。

输出的是    “YES” 和“ NO”   而不是“Yes”和“No”......../(ㄒoㄒ)/~~


壮我Spfa

开心的使用Spfa:

#include"cstdio"#include"iostream"#include"cstring"#include"algorithm"#include"vector"#include"cmath"#include"queue"using namespace std;#define INF 9999999#define inf 1009#define loop(x,y,z) for(x=y;x<z;x++)#define ll long longint n,m,p,s,g;int book[inf];int dis[inf];int cnt[inf];struct node{    int to,w;    node(int i,int j)    {        to=i;w=j;    }};vector<node>edge[inf];queue<int>q;void init(){    int i;    loop(i,1,n+1)        dis[i]=INF;    dis[s]=0;    loop(i,1,n+1)        edge[i].clear();    memset(book,0,sizeof book);    memset(cnt,0,sizeof cnt);    while(!q.empty())q.pop();}bool Spfa(){    q.push(s);    book[s]=1;    int i;    while(!q.empty())    {        int u=q.front();        q.pop();        book[u]=0;        int len=edge[u].size();        loop(i,0,len)        {            node& e=edge[u][i];            if(dis[e.to]>dis[u]+e.w)            {                dis[e.to]=dis[u]+e.w;                if(!book[e.to])                {                    q.push(e.to);                    book[e.to]=1;                    if(++cnt[e.to]>n)return false;                }            }        }    }    return true;}int main(){    int i,j,k,T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&n,&m,&p);        s=1;        init();        while(m--)        {            scanf("%d%d%d",&i,&j,&k);            edge[i].push_back(node(j,k));            edge[j].push_back(node(i,k));        }        while(p--)        {            scanf("%d%d%d",&i,&j,&k);            edge[i].push_back(node(j,-k));        }        bool t=Spfa();        if(t)printf("NO\n");        else printf("YES\n");    }    return 0;}


0 0
原创粉丝点击