zoukankan      html  css  js  c++  java
  • spfa+floyed+最长路+差分约束系统(F

    题目链接:https://cn.vjudge.net/contest/276233#problem/F

    题目大意:给你n个房子能到达的地方,然后每进入一个房子,会消耗一定的生命值(有可能是负),问你一开始在第一个方间,初始生命值是100,最终能不能从第n个房间走出?

    具体思路:首先,我们需要建图,按照正常的建立就可以了,然后再去跑一个spfa,注意这个spfa求的是最长路,然后判断一下,在没有正环的时候,看一下最终到达的n是不是正的,如果是正的,那么肯定行,否则的话,再去判断有没有正环,如果有正环,并且能够到达n点,这也是符合的情况。然后对于正环的判断,如果有正环,我们无法判断是否能到达第n个点,这个时候就需要用到floyed了,我们通过floyed判断第一个点能不能到达最后一个点,然后再判断一下中转点是不是一个正环上的点,这样的话,我们可以先通过正环加上无限的生命值,然后出去就可以了,这样又不会死。。。

    一点小感悟,如果是判断正环还是负环,我们都可以通过spfa进行判断,判断条件就是判断这个点入队列的次数和总的点数,如果一个点入队列的次数大于总的点数,那么就可以判断是正环还是负环了,但是一个spfa只能判断一种,因为用spfa判断的时候,最长路和最短路的松弛条件是不一样的,所以需要判断的话得分开判断。

     AC代码:

      1 #include<bit/stdc++.h>
      9 using namespace std;
     10 # define ll long long
     11 # define inf 0x3f3f3f3f
     12 const int maxn = 200+100;
     13 int Map[maxn][maxn];
     14 int head[maxn],vis[maxn],dis[maxn],out[maxn];
     15 struct node
     16 {
     17     int to;
     18     int cost;
     19     int nex;
     20 } edge[maxn*maxn];
     21 int n,num;
     22 void addedge(int fr,int to,int cost)
     23 {
     24     edge[num].to=to;
     25     edge[num].cost=cost;
     26     edge[num].nex=head[fr];
     27     head[fr]=num++;
     28 }
     29 void init()
     30 {
     31     memset(Map,0,sizeof(Map));
     32     for(int i=0; i<maxn; i++)
     33     {
     34        Map[i][i]=1;
     35         out[i]=0;
     36         head[i]=-1;
     37         vis[i]=0;
     38         dis[i]=-inf;
     39     }
     40     num=0;
     41 }
     42 int spfa(int st)
     43 {
     44     dis[st]=100;
     45     vis[st]=1;
     46     queue<int>q;
     47     q.push(1);
     48     while(!q.empty())
     49     {
     50         int tmp=q.front();
     51         q.pop();
     52         if(++out[tmp]>n)
     53             break;
     54         vis[tmp]=0;
     55         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
     56         {
     57             int u=edge[i].to;
     58             if(dis[u]<dis[tmp]+edge[i].cost&&dis[tmp]+edge[i].cost>0)
     59             {
     60                 dis[u]=dis[tmp]+edge[i].cost;
     61                 if(vis[u])
     62                     continue;
     63                 vis[u]=1;
     64                 q.push(u);
     65             }
     66         }
     67     }
     68     if(dis[n]>0)
     69         return 1;
     70     for(int i=1; i<=n; i++)  {
     72         for(int j=1; j<=n; j++) {
     74             for(int k=1; k<=n; k++) {
     76                 if(Map[j][i]&&Map[i][k]){
     78                     Map[j][k]=1;
     79                 }
     80             }
     81         }
     82     }
     83     for(int i=1; i<=n; i++) {
     85         if(Map[1][i]&&Map[i][n]&&out[i]>n)
     86             return 1;
     87     }
     88     return 0;
     89 }
     90 int main()
     91 {
     92     while(~scanf("%d",&n)){
     94         if(n==-1)break;
     95         init();
     96         int t,ed;
     97         for(int i=1; i<=n; i++)
     98         {
     99             int cost,ti;
    100             scanf("%d %d",&cost,&ti);
    101             while(ti--)
    102             {
    103                 scanf("%d",&ed);
    104                 addedge(i,ed,cost);
    105                 Map[i][ed]=1;
    106             }
    107         }
    108         int ans=spfa(1);
    109         if(ans==0)
    110             printf("hopeless
    ");
    111         else
    112             printf("winnable
    ");
    113     }
    114     return 0;
    115 }
    116  
  • 相关阅读:
    HDU 5058 So easy
    HDU 1392 Surround the Trees(几何 凸包模板)
    HDU 4500 小Q系列故事——屌丝的逆袭(简单题)
    HUD 5050 Divided Land
    HDU 5047 Sawtooth(大数优化+递推公式)
    http://www.rabbitmq.com/
    安装及运行 RabbitMQ 服务器 (linux) 失败! 安装erlang 失败,无法继续
    安装及运行 RabbitMQ 服务器 (windows)
    RabbitMQ client ( java )
    task:scheduled cron 合法
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262767.html
Copyright © 2011-2022 走看看