zoukankan      html  css  js  c++  java
  • SGU 219 Synchrograph tarjian找环,理解题意,图论 难度:3

    http://acm.sgu.ru/problem.php?contest=0&problem=219

    题目大意:

    如果指向某个点的边权全都为正数,那么这个点就是可点燃的,点燃操作把入弧权值-1,出弧权值都+1,

    如果在某种点燃序列之后还可以再点燃一些点使得这个点还可以点燃,那么这个点在这种点燃序列之后存活

    如果在任何点燃序列之后都还可以再点燃一些点使得这个点还可以点燃,那么这个点可存活

    现在求所有点是否可存活

    思路:

    考虑不可存活的点:对于某个状态,对于不可存活的点,要想使得没有序列可以使它被点燃,那么有边指向它的点里一定有不可存活的点,且这条边权值为0,

    如果有一个边权值都为0的环,那么在这条环上,由于权值都为0,所以这个环上的都是不可存活的点.

    所以:先通过求边权值都为0的环确定一些初始点,由这些不可存活点出发到达的点,都在某个序列下因为这些不可存活点不能提供权值而不能存活

    注意:

    1. 有自环

    2. tarjian找环需要注意更新dfn值的点在stack内,否则对于我写的形式

    会有这种情况不正确

    #include  <cstdio>
    #include <stack>
    #include <cstring>
    using namespace std;
    const int maxn=1e3+3;
    const int maxm=5e4+4;
    int n,m;
    
    int first[maxn],head[maxn];
    struct edge{
            int t,nxt;
    }e[maxm],g[maxm];
    
    int low[maxn],dp[maxn],depth;
    int alive[maxn];
    bool in[maxn];
    
    void addedge(int f,int t,int c,int ind){
            if(c==0){
                    g[ind].nxt=head[f];
                    g[ind].t=t;
                    head[f]=ind;
            }
            e[ind].nxt=first[f];
            e[ind].t=t;
            first[f]=ind;
    }
    
    stack<int> st;
    void tarjian(int s){
            low[s]=dp[s]=++depth;
            in[s]=true;st.push(s);
            for(int p=head[s];p!=-1;p=g[p].nxt){
                    int t=g[p].t;
                    if(t==s){
                            alive[s]=0;
                    }
                    if(dp[t]==0){
                            tarjian(t);
                            low[s]=min(low[s],low[t]);
                    }
                    else if(in[t]){//ATTHENTION:
                            low[s]=min(low[s],dp[t]);
                    }
            }
    
            bool single=true;
            if(low[s]==dp[s]){
                    while(st.top()!=s){
                            single=false;
                            alive[st.top()]=0;
                            
                            in[st.top()]=false;st.pop();
                    }
                    if(!single){
                            alive[st.top()]=0;
                    }
                    in[st.top()]=false;st.pop();
            }
    }
    
    void dfs(int s){
            for(int p=first[s];p!=-1;p=e[p].nxt){
                    int t=e[p].t;
                    if(alive[t]==1){
                            alive[t]=0;
                            dfs(t);
                    }
            }
    
    }
    
    int main(){
            scanf("%d%d",&n,&m);
            memset(first,-1,sizeof(first));
            memset(head,-1,sizeof(head));
            fill(alive,alive+n+1,1);
            for(int i=0;i<m;i++){
                    int f,t,c;
                    scanf("%d%d%d",&f,&t,&c);
                    addedge(f,t,c,i);
            }
    
            for(int i=1;i<=n;i++){
                    if(dp[i]==0){
                            tarjian(i);
                    }
            }
    
            for(int i=1;i<=n;i++){
                    if(alive[i]==0){
                            dfs(i);
                    }
            }
    
            for(int i=1;i<=n;i++){
                    printf("%d
    ",alive[i]);
            }
    
            return 0;
    }
    

      

  • 相关阅读:
    【转】 robotframework(rf)中对时间操作的datetime库常用关键字
    在RobotFramework--RIDE中把日期转化为整型进行运算
    Oracle中date转为timstam可以函数to_timestamp的方式来转化
    Java项目缺少.project文件
    数据库时间戳转换日期(MYSQL数据库)
    spring+struts+mybatis中关于报错org.hibernate.exception.GenericJDBCException: Connection is read-only. Queries leading to data modification are not allowed 的产生原因及解决方案
    新加字段问题(增加联合主键)
    集合问题
    数组面试题
    集合的问题
  • 原文地址:https://www.cnblogs.com/xuesu/p/4297738.html
Copyright © 2011-2022 走看看