HDU 1317 XYZZY

来源:互联网 发布:2012-2015淘宝交易数据 编辑:程序博客网 时间:2024/05/19 22:05

XYZZY

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4279    Accepted Submission(s): 1194


Problem Description
It has recently been discovered how to run open-source software on the Y-Crate gaming device. A number of enterprising designers have developed Advent-style games for deployment on the Y-Crate. Your job is to test a number of these designs to see which are winnable. 
Each game consists of a set of up to 100 rooms. One of the rooms is the start and one of the rooms is the finish. Each room has an energy value between -100 and +100. One-way doorways interconnect pairs of rooms. 

The player begins in the start room with 100 energy points. She may pass through any doorway that connects the room she is in to another room, thus entering the other room. The energy value of this room is added to the player's energy. This process continues until she wins by entering the finish room or dies by running out of energy (or quits in frustration). During her adventure the player may enter the same room several times, receiving its energy each time. 
 

Input
The input consists of several test cases. Each test case begins with n, the number of rooms. The rooms are numbered from 1 (the start room) to n (the finish room). Input for the n rooms follows. The input for each room consists of one or more lines containing: 

the energy value for room i 
the number of doorways leaving room i 
a list of the rooms that are reachable by the doorways leaving room i 
The start and finish rooms will always have enery level 0. A line containing -1 follows the last test case. 
 

Output
In one line for each case, output "winnable" if it is possible for the player to win, otherwise output "hopeless". 
 

Sample Input
50 1 2-60 1 3-60 1 420 1 50 050 1 220 1 3-60 1 4-60 1 50 050 1 221 1 3-60 1 4-60 1 50 050 1 220 2 1 3-60 1 4-60 1 50 0-1
 

Sample Output
hopelesshopelesswinnablewinnable
 

Source
题目大意:

给出 n 个房间,一开始有100个能量,下面给出 n 行,第 i 行代表第 i 个房间,其数据分别代表:当前房间的能量值(可为负),当前房间可以通向其他房间的个数,然后给出可通向其他房间的编号。
如果能够走到最后的房间,并且能量值大于 0  那么输出 win  否则输出 hope

思路:

写了一天的一个题。我的天。。。
首先用 spfa 判断是否有 正权 环。
如果它存在一个 环,并且环的能量值是正的,那么他就可以给自己无限累加能量对吧?那么就从这个环开始,判断是否可以从环这里到 n !
如果没有环,就正常用 Dijkstra 解就可以啦。
这是一种思路。
另一种思路是 先用 Floyd 找出联通路。然后 bellman_ford 求最短路。求解的过程也是同样的。 bellman_ford   之后直接可以得到结果。

感想:

这个题写了好久...wa 了至少 8 次后来于是换了一种写法,(网上说 spfa 不可以解这个题) 后来在写这篇博客的时候想到了一个地方有漏洞。补上之后就 AC 了。哈哈  我用 spfa 解决了这个题。而且用最基本的   Dijkstra  不过就是代码有些乱。啦啦 好开心。

AC代码:

spfa + Dijkstra 

#include<string.h>#include<stdio.h>#include<vector>#include<queue>#include<iostream>using namespace std;const int INF = -0x3f3f3f3f;struct road{    int en,cost;    friend bool operator < (const road &a,const road &b)    {        return a.cost>b.cost;    }};bool vis[10005];vector<road> v[10005];priority_queue<road> que;road p,q;int n;int dist[10005];int update[10005];int lalala;int spfa(int cc){    for(int i=1;i<=n;i++)        dist[i]=INF;    dist[cc]=100;    queue<int> que;    que.push(cc);    memset(update,0,sizeof(update));    while(!que.empty())    {        int s=que.front();        que.pop();        for(int i=0;i<v[s].size();i++)        {            int e=v[s][i].en;            if(dist[s]+v[s][i].cost>dist[e]&&dist[s]+v[s][i].cost>0)            {                dist[e]=dist[s]+v[s][i].cost;                que.push(e);                update[e]++;                if(update[e]>=n)                {                    lalala=e;                    return true;                }            }        }    }    return false;}int main(){    int cost,m,en,i,j,k;    while(scanf("%d",&n))    {        if(n==-1)            break;        for(i=0;i<=n;i++)            v[i].clear();        memset(vis,0,sizeof(vis));        int falg;        for(k=1;k<=n;k++)        {            scanf("%d%d",&cost,&m);            for(i=0;i<m;i++)            {                scanf("%d",&en);                p.cost=cost;                p.en=en;                v[k].push_back(p);            }        }//数据的初始化        queue<int> pq;        if(spfa(1))        {            int to;            to=lalala;            pq.push(to);            falg=0;            while(!pq.empty())            {                to=pq.front();                pq.pop();                if(vis[to])                    continue;                vis[to]=true;                if(to==n)                {                    falg=1;                    break;                }                for(i=0;i<v[to].size();i++)                {                    int toto=v[to][i].en;                    if(vis[toto])                        continue;                    pq.push(toto);                }            }            if(falg)                cout<<"winnable"<<endl;            else                cout<<"hopeless"<<endl;            continue;        }        road now,next;        now.en=0;        now.cost=0;        que.push(now);        falg=0;        next.en=1;        next.cost=100;        v[0].push_back(next);        memset(vis,0,sizeof(vis));        while(!que.empty())        {            now=que.top();            que.pop();            if(vis[now.en])                continue;            vis[now.en]=true;            //cout<<now.en<<" "<<now.cost<<endl;            if(now.en==n)            {                falg=1;                break;            }            for(i=0;i<v[now.en].size();i++)            {                next.en=v[now.en][i].en;                if(vis[next.en])                    continue;                next.cost=now.cost+v[now.en][i].cost;                if(next.cost>0)                    que.push(next);                //cout<<"next "<<next.en<<endl;            }        }        if(falg)            cout<<"winnable"<<endl;        else            cout<<"hopeless"<<endl;        while(!que.empty())        {            que.pop();        }        while(!pq.empty())        {            pq.pop();        }    }    return 0;}


Floyd +  bellman_ford 

#include<iostream>#include<string.h>#include<stdio.h>#include<vector>#include<queue>using namespace std;const int INF = -0x3f3f3f3f;struct road{    int sta,en;};int map[105][105];int cost[105];int n,num;vector<road> v;int dis[105];void Floyd(){    int i,j,k;    for(k = 1; k<=n; k++)        for(i = 1; i<=n; i++)            for(j = 1; j<=n; j++)                if(!map[i][j])                    map[i][j] = map[i][k]&&map[k][j];}int bellman_ford(){    for(int i=0;i<=n;i++)        dis[i]=INF;    dis[1]=100;    for(int k=1;k<=n-1;k++)    {        for(int i=0;i<num;i++)        {            int s=v[i].sta;            int en=v[i].en;            if(dis[en]<dis[s]+cost[en]&&dis[s]+cost[en]>0)            {                dis[en]=dis[s]+cost[en];            }        }    }    for(int i=0;i<num;i++)    {        int s=v[i].sta;        int en=v[i].en;        if(dis[en]<dis[s]+cost[en])        {            if(dis[s]+cost[en]>0&&map[en][n])                return 1;        }    }    return 0;}int main(){    int k,i,j,m,to;    road now;    while(scanf("%d",&n))    {        if(n==-1)            break;        num=0;        memset(map,0,sizeof(map));        v.clear();        for(k=1;k<=n;k++)        {            scanf("%d%d",&cost[k],&m);            for(i=0;i<m;i++)            {                scanf("%d",&to);                now.sta=k;                now.en=to;                v.push_back(now);                map[k][to]=1;                num++;            }        }        Floyd();        if(bellman_ford())        {            cout<<"winnable"<<endl;        }        else        {            if(dis[n]>0)                cout<<"winnable"<<endl;            else                cout<<"hopeless"<<endl;        }    }    return 0;}



0 0
原创粉丝点击