UVALIVE 3307 Adventurous Driving

一开始重新建图搞的。然后参照了别人的博客。这个解法比较好

利用在SPFA维护入队次数。入队次数大于节点数目的位于负环。

那么负环中的点如何DFS到终点。(SPFA从起点开始如果能找到入队大于N那么一定可以从起点到这个点)那么就NOBOUND;

VOID和输出ANS就比较容易了

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
#define MAXN 2000
#define MAXM 20010
const int INF = 0x3f3f3f3f;
int N,M,A,B;
struct node
{
        int u,v,next;
        int length,weight;
}edge[MAXM];
int head[MAXN],cnt;
int num[MAXN],d[MAXN],l[MAXN];
bool inq[MAXN],used[MAXN];
int q[MAXM];
bool found;
void insert(int u ,int v,int weight,int length)
{
        if (head[u] != -1 && weight > edge[head[u]].weight) return;
        if (head[u] != -1 && weight < edge[head[u]].weight) head[u] = -1;
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].weight = weight;
        edge[cnt].length = length;
        edge[cnt].next = head[u];
        head[u]  = cnt++;
}
void read()
{
        memset(head,-1,sizeof(head));
        cnt = 0;
        for (int i = 0 ; i < M; i++)
        {
                int u ,v, weightl,weightr,length;
               // if (i != M - 1)
                        scanf("(%d,%d,%d[%d]%d) ",&u,&v,&weightl,&length,&weightr);
               // else  scanf("(%d,%d,%d[%d]%d)",&u,&v,&weightl,&length,&weightr);
                //printf("%d %d %d %d %d \n",u,v,weightl,length,weightr);
                insert(u,v,weightl,length);
                insert(v,u,weightr,length);
        }
}
bool SPFA(int s)
{
        int front = 0,rear = 1;
        memset(inq,false,sizeof(inq));
        memset(num,0,sizeof(num));
        memset(d,0x3f,sizeof(d));
        memset(l,0x3f,sizeof(l));
        inq[s] = true;
        q[0] = s;
        d[s] = l[s] = 0;
        num[s] = 1;
        while (front !=rear)
        {
                int u = q[front] ;
                front = (front + 1) % MAXM;
                inq[u] = false;
                for (int i = head[u]; i != -1 ; i = edge[i].next)
                {
                        int v = edge[i].v;
                        if (d[v] > d[u] + edge[i].weight ||( (d[v] == d[u] + edge[i].weight) && (l[v] > l[u] + edge[i].length)))
                        {
                                d[v] = d[u] + edge[i].weight;
                                l[v] = l[u] + edge[i].length;
                                if (!inq[v])
                                {
                                        inq[v] = true;
                                        num[v]++;
                                        q[rear] = v;
                                        rear = (rear + 1) % MAXM;
                                        if (num[v] > N + 4) return false;
                                }
                        }
                }
        }
        return true;
}
void dfs(int cur)
{
        used[cur] = true;
        if (cur == B) {found = true; return;}
        for (int i = head[cur]; i != -1; i = edge[i].next)
        {
                int  v = edge[i].v;
                if (!used[v]) dfs(v);
        }
}
int main()
{
       // freopen("sample.txt","r",stdin);
        while (scanf("%d%d%d%d ",&N,&M,&A,&B) != EOF)
        {
                found = false;
                read();
                bool flag = SPFA(A);
                if (d[B] == INF) puts("VOID");
                else
                {
                        if (flag) printf("%d %d\n",d[B],l[B]);
                        else
                        {
                                for (int i = 0 ; i < N; i++)
                                        if (num[i] > N)
                                {
                                        memset(used,false,sizeof(used));
                                        found = false;
                                        dfs(i);
                                        if (found) break;
                                }
                                if (found || num[B] > N) puts("UNBOUND");
                                else printf("%d %d\n",d[B],l[B]);
                        }
                }
        }
        return 0;
}

 

posted @ 2014-10-22 22:45  Commence  阅读(185)  评论(0编辑  收藏  举报