Problem 1 Graph (graph.cpp/c/pas)

 

【题目描述】

给出 N 个点,M 条边的有向图,对于每个点 v,求 A(v) 表示从点 v 出发,能到达的编号最大的点。

 

【输入格式】

第 1 行,2 个整数 N,M。 接下来 M 行,每行 2 个整数 Ui,Vi,表示边 ⟨Ui,Vi⟩。点用 1,2,...,N 编号。

 

【输出格式】

N 个整数 A(1),A(2),...,A(N)。

 

【样例输入】

4 3

1 2

2 4

4 3

【样例输出】

4 4 3 4

【数据范围】

对于 60% 的数据,1 ≤ N,K ≤ 10^3

对于 100% 的数据,1 ≤ N,M ≤ 10^5。

 

题解:

暴力+错误tarjan缩点

先写的缩点,对拍半天,补了n个漏洞,跑大数据平均10个WA3个

两个程序就一起交了。略丑。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N 100008
using namespace std;
int n,m,sumedge;
queue<int>q;
int head[N];

int ans[N],vis[N];

int top,tim,sumcol;

int low[N],dfn[N],Stack[N],instack[N],bel[N],mx[N];

int cd[N],rd[N];

inline int read(){
    char ch=getchar();int x=0,f=1;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}

struct Edge{
    int x,y,nxt;
    Edge(int x=0,int y=0,int nxt=0):
        x(x),y(y),nxt(nxt){}
}edge[N];

void add(int x,int y){
    edge[++sumedge]=Edge(x,y,head[x]);
    head[x]=sumedge;
}

void bfs(int x){
    memset(vis,0,sizeof(vis));
    vis[x]=true;
    while(!q.empty())q.pop();
    q.push(x);
    while(!q.empty()){
        int now=q.front();q.pop();
        ans[x]=max(ans[x],now);
        for(int i=head[now];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(!vis[v]){
                q.push(v);vis[v]=1; 
            }
        }
    }
}

void tarjian(int x){
    low[x]=dfn[x]=++tim;
    Stack[++top]=x;instack[x]=true;
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(instack[v])low[x]=min(low[x],dfn[v]);
        else if(!dfn[v]){
            tarjian(v);
            low[x]=min(low[x],low[v]);
        }
    }
    if(low[x]==dfn[x]){
        sumcol++;
        while(Stack[top+1]!=x){
            bel[Stack[top]]=sumcol;
            instack[Stack[top]]=false;
            mx[sumcol]=max(mx[sumcol],Stack[top]);
            top--;
        }
    }
}

void dfs(int x){
    for(int i=head[x];i;i=edge[i].nxt){
        int v=edge[i].y;
        if(bel[x]==bel[v])continue;
        dfs(v);
        ans[bel[x]]=max(ans[bel[x]],ans[bel[v]]);
    }
    return;
}

int main(){
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=m;i++){
        int x,y;
        x=read();y=read();
        add(x,y);
    }
    if(n<=3000){
        for(int i=1;i<=n;i++)bfs(i);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
        return 0;
        fclose(stdin);fclose(stdout);
    }
    for(int i=1;i<=n;i++)if(!dfn[i])tarjian(i);
    for(int x=1;x<=n;x++){
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(bel[v]!=bel[x]) cd[bel[x]]++,rd[bel[v]]++;
        }
    }
      for(int i=1;i<=n;i++)ans[bel[i]]=mx[bel[i]];
    for(int i=1;i<=n;i++)if(!rd[bel[i]])dfs(i);
    for(int i=1;i<=n;i++)printf("%d ",max(ans[bel[i]],mx[bel[i]]));
    fclose(stdin);fclose(stdout);
    return 0;
}
80

相关文章:

  • 2021-06-15
  • 2021-04-02
  • 2021-08-12
  • 2021-12-25
  • 2021-05-27
  • 2021-09-06
  • 2022-01-20
  • 2021-04-06
猜你喜欢
  • 2021-08-19
  • 2022-12-23
  • 2021-04-18
  • 2021-07-06
  • 2021-12-28
  • 2021-12-15
相关资源
相似解决方案