首页 > 其他 > 详细

【好题】图论+思维——cf1344C/cf1345E

时间:2020-05-08 12:59:43      阅读:56      评论:0      收藏:0      [点我收藏+]
/*
u<v,那么u->v连边,形成一个DAG
如果u选择的是全称量词,那么所有u出发可达的点v,显然有u<v,所以v必须是存在量词 
                       所有可以到达u的点v,显然有u>v,所以v必须是存在量词 
由于必须从左到右进行,所以如果a[i]是存在量词,那么a[i]可达的a[i+k],可达a[i]的a[i+k]都必须为存在量词 

建立正反两张图 
从1开始依次扫描下去,如果没确定是存在量词,那么就可以判定为全称量词
    然后在两张图中把ai可达的点都访问一遍,标为存在量词 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005

int n,m,in[N],ans[N],vis1[N],vis2[N];
vector<int>G1[N],G2[N];

void dfs1(int u){
    vis1[u]=1;
    for(auto v:G1[u])
        if(!vis1[v])dfs1(v);
}
void dfs2(int u){
    vis2[u]=1;
    for(auto v:G2[u])
        if(!vis2[v])dfs2(v); 
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        in[v]++;
        G1[u].push_back(v);
        G2[v].push_back(u);
    }
    
    queue<int>q;
    int cnt=0;
    for(int i=1;i<=n;i++)
        if(in[i]==0)q.push(i);    
    while(q.size()){
        cnt++;
        int u=q.front();q.pop();
        for(auto v:G1[u]){
            in[v]--;
            if(in[v]==0)
                q.push(v);
        }
    }
    if(cnt!=n){puts("-1");return 0;}
    
    cnt=0;
    for(int i=1;i<=n;i++){
        if(!vis1[i] && !vis2[i]){
            cnt++;ans[i]=1;
        }
        if(!vis1[i])dfs1(i);
        if(!vis2[i])dfs2(i);
    }
    
    cout<<cnt<<\n;
    for(int i=1;i<=n;i++)
        if(ans[i])cout<<"A";
        else cout<<"E";
}

 

【好题】图论+思维——cf1344C/cf1345E

原文:https://www.cnblogs.com/zsben991126/p/12849450.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!