• UVA 10557 XYZZY


    UVA_10557

    这个题目实际上是求一个从起点到终点的最长路。

    但是由于路过每个点时权值都不能为负,所以我们在初始化距离数组d[]时要初始化0。之后就是用队列优化的Bellman-Ford算法去求最长路了,但是还有一些细节需要注意。

    我们当然可以在用这个算法时选择d[n]>0是就跳出循环来减少计算量,但也会找到使这个算法崩溃的例子,比如在某个位置存在一个正圈,而由这个正圈却不能到达终点,那么程序就会一直跑下去。但同样的,我们也不能见圈就跳,因为毕竟还是有些正圈可以到达终点的。这便要求我们去判断哪些正圈可以到达终点。

    于是我们可以选择在找最长路之前先做一下预处理,把所有能够到达终点的点找出来,一个比较好的办法就是从终点开始逆向深搜,然后依次标记搜到的点即可,如果最后起点没有被标记,那就直接输出hopeless就可以了。

    后面在使用队列优化的Bellman-Ford算法时,我们在判断条件上多加一个是否可达终点的判断即可,如果该点可达终点我们再进行求最长路的操作。

    #include<stdio.h>
    #include
    <string.h>
    int G[110][110],w[110],d[110],n;
    int q[110],inq[110],inedq[110];
    int vis[110],reach[110];
    void dfs(int v)
    {
    int u;
    for(u=1;u<=n;u++)
    if(G[u][v]&&!vis[u])
    {
    vis[u]
    =1;
    reach[u]
    =1;
    dfs(u);
    }
    }
    int main()
    {
    int i,j,k,u,v,num,front,rear,flag;
    while(1)
    {
    scanf(
    "%d",&n);
    if(n==-1)
    break;
    memset(G,
    0,sizeof(G));
    for(u=1;u<=n;u++)
    {
    scanf(
    "%d",&w[u]);
    scanf(
    "%d",&num);
    for(i=0;i<num;i++)
    {
    scanf(
    "%d",&v);
    G[u][v]
    =1;
    }
    }
    memset(vis,
    0,sizeof(vis));
    memset(reach,
    0,sizeof(reach));
    reach[n]
    =1;
    dfs(n);
    if(!reach[1])
    {
    printf(
    "hopeless\n");
    continue;
    }
    memset(inq,
    0,sizeof(inq));
    memset(inedq,
    0,sizeof(inedq));
    memset(d,
    0,sizeof(d));
    front
    =rear=0;
    d[
    1]=100;
    q[rear
    ++]=1;
    inq[
    1]=1;
    inedq[
    1]++;
    flag
    =0;
    while(front!=rear)
    {
    u
    =q[front++];
    if(front>n)
    front
    =0;
    inq[u]
    =0;
    for(v=1;v<=n;v++)
    if(G[u][v]&&reach[v]&&d[u]+w[v]>d[v])
    {
    d[v]
    =d[u]+w[v];
    if(!inq[v])
    {
    q[rear
    ++]=v;
    if(rear>n)
    rear
    =0;
    inq[v]
    =1;
    if(inedq[v]++>n)
    {
    flag
    =1;
    break;
    }
    }
    }
    if(d[n]>0||flag)
    break;
    }
    if(d[n]>0||flag)
    printf(
    "winnable\n");
    else
    printf(
    "hopeless\n");
    }
    return 0;
    }

      

  • 相关阅读:
    .net网络编程(4)TcpListener、TcpClient
    Win32 窗口篇(1)
    Win32 窗口篇(3)
    JS数组定义
    asp的RegExp对象正则表达式功能用法
    Javascript 面向对象全新理练之数据的封装
    asp 正则表达式
    PPK 谈 JavaScript 的 this 关键字
    JavaScript 接收键盘指令示例
    javascript事件列表解说
  • 原文地址:https://www.cnblogs.com/staginner/p/2172821.html
Copyright © 2020-2023  润新知