zoukankan      html  css  js  c++  java
  • 10.18T2 tarjan缩点+分层图SPFA

    吃土的DLZ

    Problem Background

    众所周知,DLZ喜欢吃土,总有一天,他要把学校的土吃完。

    Problem Description

    DLZ终于想起了他还要吃土,为了弥补之前一直没有吃土的遗憾,他决定这次要尽 可能去更多的地方吃土,学校可以看做有n个点联通的有向图,DLZ可以在学校随意游 走。DLZ所在的教室为一号节点,由于他还要上课,所以他必须在吃完土之后回到一号 节点。DLZ不是一般人,可以在学校的道路上逆行当路霸,但是DLZ是有高度社会责任 感的人,他不会为了一己私利而频繁破坏学校秩序,所以他最多只会逆行一次。额,那 么,有奖竞猜开始了,DLZ最多会去几个地方吃土?获胜者将获得bashu无限饭卡

    Input

    第一行两个整数nm

    2到第m+1行,每行两个整数xy,表示有一条xy的有向边

    Output

    一个整数,DLZ最多会去几个点。

    Sample Input

    7 10

    1 2

    3 1

    2 5

    2 4

    3 7

    3 5

    3 6

    6 5

    7 2

    4 7

    Sample Output

    6

    Data Scale

    测试数据点

    n

    m

    1~4

    100

    500

    5,6

    10000

    20000

    7~14

    100000

    100000

    首先很显然一个联通块内可以不逆行任意到达,所以我们tarjan缩个点

    然后发现只用一次逆行与分层图很像,把dis分成两个dis[x][1]和dis[x][0]代表没使用和使用,跑一个分层图而不是枚举每条边了,复杂度期望O(n+m)

    在调的时候还是循环i,j搞混,引以为戒,同时慎用位运算判奇偶

    说实话还是比较简单的

    code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<cstring>
      5 #define N 500005
      6 using namespace std;
      7 struct node {
      8     int u,v,w;
      9 } e[N],e1[N];
     10 int first[N],nxt[N],cnt;
     11 void add(int u,int v){
     12     e[++cnt].u=u;
     13     e[cnt].v=v;
     14     nxt[cnt]=first[u];
     15     first[u]=cnt;
     16 }
     17 int first1[N],nxt1[N],cnt1;
     18 void add1(int u,int v,int w) {
     19     e1[++cnt1].u=u;
     20     e1[cnt1].v=v;
     21     e1[cnt1].w=w;
     22     nxt1[cnt1]=first1[u];
     23     first1[u]=cnt1;
     24 }
     25 int dfn[N],low[N],sign,instack[N],stack[N],top,bcc,belong[N],siz[N];
     26 void tarjan(int x) {
     27     dfn[x]=low[x]=++sign;
     28     instack[x]=1;
     29     stack[++top]=x;
     30     for(int i=first[x]; i; i=nxt[i]) {
     31         int v=e[i].v;
     32         if(!dfn[v]) {
     33             tarjan(v);
     34             low[x]=min(low[x],low[v]);
     35         } else if(instack[v])low[x]=min(low[x],dfn[v]);
     36     }
     37     if(dfn[x]==low[x]) {
     38         int t;
     39         bcc++;
     40         do {
     41             siz[bcc]++;
     42             t=stack[top--];
     43             belong[t]=bcc;
     44             instack[t]=0;
     45         } while(t!=x);
     46     }
     47 }
     48 int max0=0;
     49 int num[N],check[N];
     50 int f[N][2];
     51 struct T{
     52     int u,is;
     53 };
     54 int dis[N][2],vis[N<<1],now;
     55 void spfa(){
     56     queue<int>q;    
     57     memset(vis,0,sizeof vis);
     58     memset(dis,0,sizeof dis);
     59     dis[now][1]=0;
     60     vis[now*2+1]=1;
     61     q.push(now*2+1);
     62     while(!q.empty()){
     63         int u=q.front();
     64         q.pop();
     65         vis[u]=0;
     66         for(int i=first1[u/2];i;i=nxt1[i]){
     67             int v=e1[i].v;
     68             if(e1[i].w){
     69                 if(u%2){
     70                     if(dis[v][0]<dis[u/2][1]+siz[v]){
     71                         dis[v][0]=dis[u/2][1]+siz[v];
     72                         if(!vis[2*v]){
     73                             vis[2*v]=1;
     74                             q.push(2*v);
     75                         }
     76                     }
     77                 }
     78             }
     79             else{
     80                 if(dis[v][u%2]<dis[u/2][u%2]+siz[v]){
     81                     dis[v][u%2]=dis[u/2][u%2]+siz[v];
     82                     if(!vis[2*v+u%2]){
     83                         vis[2*v+u%2]=1;
     84                         q.push(2*v+u%2);
     85                     }
     86                 }
     87             }
     88         }
     89     }
     90 }
     91 int read(){
     92     int x=0,f=1;
     93     char c=getchar();
     94     while(!isdigit(c)){
     95         if(c=='-')f=-1;
     96         c=getchar();
     97     }
     98     while(isdigit(c)){
     99         x=(x<<3)+(x<<1)+c-'0';
    100         c=getchar();
    101     }
    102     return x*f;
    103 }
    104 int main() {
    105     freopen("soil.in","r",stdin);
    106     freopen("soil.out","w",stdout);
    107     int n,m;
    108     n=read(),m=read();
    109     for(int i=1; i<=m; i++) {
    110         int u,v;
    111         u=read(),v=read();
    112         add(u,v);
    113     }
    114     for(int i=1;i<=n;i++)
    115     if(!dfn[i])tarjan(i);
    116     now=belong[1];
    117     for(int i=1; i<=cnt; i++) {
    118         if(belong[e[i].u]==belong[e[i].v])continue;
    119         add1(belong[e[i].u],belong[e[i].v],0);
    120         add1(belong[e[i].v],belong[e[i].u],1);
    121     }
    122     spfa();
    123     cout<<max(dis[now][0],1);
    124     return 0;
    125 }

    over

  • 相关阅读:
    Node + js实现大文件分片上传基本原理及实践(一)
    渐进式web应用开发---promise式数据库(五)
    渐进式web应用开发---使用indexedDB实现ajax本地数据存储(四)
    渐进式web应用开发--拥抱离线优先(三)
    js实现使用文件流下载csv文件
    客户端持久化数据库---indexedDB使用
    渐进式web应用开发---service worker (二)
    渐进式web应用开发---service worker 原理及介绍(一)
    浅谈NodeJS多进程服务架构基本原理
    Electron为文件浏览器创建图标(三)
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9809802.html
Copyright © 2011-2022 走看看