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

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;
}


posted @ 2016-11-29 22:48  see_you_later  阅读(176)  评论(0编辑  收藏  举报