• loj 1108(spfa判负环)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26823

    思路:题目的意思是求出所有的能够到达负环的点。负环很好求,spfa即可,然后要求那些可以到达负环的点,其实我们可以反过来想,从负环出发,看能够达到那些顶点。于是我们可以建反图搞定。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<vector>
     7 using namespace std;
     8 #define MAXN 1111
     9 #define inf 1<<30
    10 
    11 struct Edge{
    12     int v,w;
    13     Edge(){}
    14     Edge(int vv,int ww):v(vv),w(ww){}
    15 };
    16 
    17 int n,m,flag;
    18 int dist[MAXN],_count[MAXN];
    19 bool mark[MAXN],vis[MAXN],In_graph[MAXN];
    20 
    21 vector<vector<Edge> >g;
    22 
    23 void dfs(int u)
    24 {
    25     vis[u]=true;
    26     for(int i=0;i<g[u].size();i++){
    27         int v=g[u][i].v;
    28         if(!vis[v])dfs(v);
    29     }
    30 }
    31 
    32 void spfa(int st)
    33 {
    34     memset(mark,false,sizeof(mark));
    35     memset(_count,0,sizeof(_count));
    36     fill(dist,dist+n+1,inf);
    37     queue<int>que;
    38     que.push(st);
    39     dist[st]=0;
    40     while(!que.empty()){
    41         int u=que.front();
    42         que.pop();
    43         mark[u]=false;
    44         _count[u]++;
    45         if(_count[u]>n){
    46             flag=1;
    47             dfs(u);
    48         }
    49         for(int i=0;i<g[u].size();i++){
    50             int v=g[u][i].v,w=g[u][i].w;
    51             if(vis[v])continue;
    52             if(dist[u]+w<dist[v]){
    53                 dist[v]=dist[u]+w;
    54                 if(!mark[v]){
    55                     mark[v]=true;
    56                     que.push(v);
    57                 }
    58             }
    59         }
    60     }
    61 }
    62 
    63 int main()
    64 {
    65     int _case,u,v,w,t=1;
    66     scanf("%d",&_case);
    67     while(_case--){
    68         scanf("%d%d",&n,&m);
    69         g.clear();
    70         g.resize(n+2);
    71         while(m--){
    72             scanf("%d%d%d",&u,&v,&w);
    73             g[v].push_back(Edge(u,w));
    74         }
    75         memset(vis,false,sizeof(vis));
    76         flag=0;
    77         for(int i=0;i<n;i++)spfa(i);
    78         printf("Case %d:",t++);
    79         if(!flag){
    80             puts(" impossible");
    81         }else{
    82             for(int i=0;i<n;i++)if(vis[i])printf(" %d",i);
    83             puts("");
    84         }
    85     }
    86 }
    View Code
  • 相关阅读:
    (Vedctor经典)A
    C++ map用法
    (约瑟夫应用)5.4.1 Roman Roulette
    部分题集代码
    随机生成数
    如何在AutoCAD中实现鼠标双击事件
    浅谈JS之Error对象
    自定义微信小程序swiper轮播图面板指示点的样式
    物理像素与逻辑像素相关概念
    微信小程序中padding-right和margin-right无效
  • 原文地址:https://www.cnblogs.com/wally/p/3341340.html
Copyright © 2020-2023  润新知