zoukankan      html  css  js  c++  java
  • 消息扩散

    题目背景

    本场比赛第一题,给个简单的吧,这 100 分先拿着。

    题目描述

    有n个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出n个城市及其之间的道路,问至少需要在几个城市发布消息才能让这所有n个城市都得到消息。

    输入输出格式

    输入格式:

    第一行两个整数n,m表示n个城市,m条单向道路。

    以下m行,每行两个整数b,e表示有一条从b到e的道路,道路可以重复或存在自环。

    输出格式:

    一行一个整数,表示至少要在几个城市中发布消息。

    输入输出样例

    输入样例#1: 
    5 4
    1 2
    2 1
    2 3
    5 1
    
    输出样例#1:
    2
    

    说明

    【数据范围】

    对于20%的数据,n≤200;

    对于40%的数据,n≤2,000;

    对于100%的数据,n≤100,000,m≤500,000.

    【限制】

    时间限制:1s,内存限制:256M

    【注释】

    样例中在4,5号城市中发布消息。

    分析:

    本题很简单???我做了好多遍。。。先%%%牛的传说帮我改对了这题。

    本题思路就是求强连通分量,但是去重很麻烦,最后看到了题解判断入度才豁然开朗em。。。

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<stack>
     4 #include<cstring>
     5 using namespace std;
     6 const int M=5000005;
     7 int n,m;
     8 int next[M],to[M],head[M];
     9 int ans;
    10 int du[M];
    11 inline int get(){
    12     char c=getchar();
    13     int res=0;
    14     while (c>'9'||c<'0') c=getchar();
    15     while (c<='9'&&c>='0') {
    16         res=(res<<3)+(res<<1)+c-'0';
    17         c=getchar();
    18     }
    19     return res;
    20 }
    21 int tot;
    22 inline void add(int u,int v){
    23     next[++tot]=head[u];
    24     head[u]=tot;
    25     to[tot]=v;
    26 }
    27 int low[M],dfn[M];
    28 bool vis[M];
    29 int in,now;
    30 stack<int> q;
    31 int f[M];
    32 void tarjan(int u){
    33     dfn[u]=low[u]=++in;
    34     q.push(u);
    35     vis[u]=true;
    36     for (int i=head[u];i;i=next[i]){
    37         int v=to[i];
    38         if (dfn[v]==-1){
    39             tarjan(v);
    40             low[u]=min(low[u],low[v]);
    41         }
    42         else if (vis[v]) low[u]=min(low[u],dfn[v]);
    43     }
    44     int v;
    45     if (dfn[u]==low[u]){
    46         now++;
    47         do {
    48             v=q.top();
    49             f[v]=now;
    50             vis[v]=false;
    51             q.pop();
    52         }while (u!=v);
    53     }
    54 }
    55 int main(){
    56     n=get(),m=get();
    57     for (int i=1;i<=m;i++){
    58         int x=get(),y=get();
    59         if (x!=y) add(x,y);
    60     }
    61     memset(vis,false,sizeof(vis));
    62     memset(dfn,-1,sizeof(dfn));
    63     for (int i=1;i<=n;i++)
    64         if (dfn[i]==-1) tarjan(i);
    65     for (int i=1;i<=n;i++){
    66         for (int j=head[i];j;j=next[j]){
    67             int z=to[j];
    68             if (f[i]!=f[z]) du[f[z]]++;
    69         }
    70     }
    71     //cout<<now<<endl;
    72     for (int i=1;i<=now;i++){
    73         //cout<<du[i]<<endl;
    74         ans+=(du[i]==0);
    75     }
    76     cout<<ans<<endl;
    77     return 0;
    78 }
  • 相关阅读:
    关于Unity中资源打包
    关于Unity中的物理
    关于Unity中特殊目录
    关于Unity中脚本
    千八行
    早春游园
    西湖冬景
    七尖行
    黄山游记
    四季
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11146168.html
Copyright © 2011-2022 走看看