洛谷—— P3469 [POI2008]BLO-Blockade

题目描述

There are exactly  towns in Byteotia.

Some towns are connected by bidirectional roads.

There are no crossroads outside towns, though there may be bridges, tunnels and flyovers. Each pair of towns may be connected by at most one direct road. One can get from any town to any other-directly or indirectly.

Each town has exactly one citizen.

For that reason the citizens suffer from loneliness.

It turns out that each citizen would like to pay a visit to    every other citizen (in his host's hometown), and do it    exactly once. So exactly ![](

That's right, should.

Unfortunately, a general strike of programmers, who demand an emergency purchase of software, is under way.

As an act of protest, the programmers plan to block one town of Byteotia, preventing entering it, leaving it, and even passing through.

As we speak, they are debating which town to choose so that the consequences are most severe.

Task Write a programme that:

reads the Byteotian road system's description from the standard input, for each town determines, how many visits could take place if this town were not blocked by programmers, writes out the outcome to the standard output.

给定一张无向图,求每个点被封锁之后有多少个有序点对(x,y)(x!=y,1<=x,y<=n)满足x无法到达y

输入输出格式

输入格式:

In the first line of the standard input there are two positive integers:  and  () denoting the number of towns and roads, respectively.

The towns are numbered from 1 to .

The following  lines contain descriptions of the roads.

Each line contains two integers  and  () and denotes a direct road between towns numbered  and .

输出格式:

Your programme should write out exactly  integers to the standard output, one number per line. The  line should contain the number of visits that could not take place if the programmers blocked the town no. .

输入输出样例

输入样例#1:

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

8
8
16
14
8

思路:

我们来看一下这道题。

思考一下我们要怎样做呢??

看到题目:给定一张无向图,求每个点被封锁之后有多少个有序点对(x,y)(x!=y,1<=x,y<=n)满足x无法到达y以后大佬们就应该猜到了这道题的大致做法:图论。

我们看到样例以后肯定事先不管他三七二十一,先连起边来再说。。

但是连完边以后呢??

有位大佬说:我们连起边以后先把与这个点直接相连的边删掉,然后再判断有几块联通快,又因为每一块联通快内的所有点又都是联通的,所以每一块联通块所不能到达的就是与他不连通的每一块的点数,累加就好了,但由于数据太大,我们就要用树形dp来优化。。。。

但蒟蒻表示并不会树形dp啊。。。。

哎,无奈只能考虑别的做法了。。。。

我们先来看对于被割掉的这个点来说他所不能到达的点恰好是整张图上所有的点(除她自己之外(废话,他肯定能自己到达自己了!!))这样他所不能联通的共有:从他出去到所有的点,从所有的点出去到他,也就是说共有:(n-1)*2对。

再就是对于其他的联通快,我们只需要预处理出每一个点出发到达的点然后再*2就好了。。

又有人要问了:怎样预处理???!!

我们来样例来看一下;;

对于割掉点3来说:不能到达的点是这样来的呢??

割掉点三之后:我们把整张图分成了这样三部分:(1,2),(3),(4,5)。

点1不能到达的点就是(1,3)(1,4)(1,5);

点2不能到达的点为(2,3),(2,4,)(2,5)

点3不能到达的点为((3,1),(3,2),(3,4,),(3,5)

点4.。。。。。。。((4,1)(4,2)(4,3)

点5.。。。。。。。(5,1)(5,2)(5,3)

由于我们要*2嘛,所以这个地方我们只能出已成一对的形式

这样就还剩下(1,3)(1,4)(1,5)(2,3)(2,4)(2,5)(3,4)(3,5)

看看这些,你能发现什么?!

是不是这样对于这个图来说好理解一些

(反掌我是没太理解。。。)

但是这里我们可以用别的来做:我们对于一个点出去他所到达的和能到达它的之外。剩下的就是他相连的联通块之间的相连的了。

我们在来处理这一部分。在tarjan里面,我们处理出这个点所能到达且是他的子树的的联通块的大小,这样他的父亲树的大小就为总点数减去这个点减去他的子树的大小,即n-1-size[i] i为当前点。 这样我们又能得知他们之间不能相连的点数就是他的父亲节点内的个数*塔子树节点内的个数、。即ans【i】=t*(n-t-1) t=size[i] 这样我们求出了从该点外不能互相到达的对数

再加上它能到达的点的对数就是了。不过这里我们处理出来的是单向到达,我们在输出时再乘以二就好了!!

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100005
#define ll long long
using namespace std;
int n,m,x,y,tot,tim;
int dfn[N],low[N],size[N],head[N],cut_point[N];
ll ans[N];
int read()
{
    ,f=; char ch=getchar();
    ; ch=getchar();}
    +ch-';ch=getchar();}
    return x*f;
}
struct Edge
{
    int from,next,to;
}edge[];
void add(int x,int y)
{
    tot++;
    edge[tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
int tarjan(int now)
{
    ;size[now]=;
    dfn[now]=low[now]=++tim;
    for(int i=head[now];i;i=edge[i].next)
    {
        int t=edge[i].to;
        if(!dfn[t])
        {
            tarjan(t);
            size[now]+=size[t];
            low[now]=min(low[now],low[t]);
            if(dfn[now]<=low[t])
            {
                ans[now]+=(ll)z*size[t];
                z+=size[t];
            }
        }
        else low[now]=min(low[now],dfn[t]);
    }
    ans[now]+=(ll)z*(n-z-);
}
int main()
{
    n=read();m=read();
    ;i<=m;i++)
     x=read(),y=read(),add(x,y),add(y,x);
    tarjan();
    ;i<=n;i++)
      printf()<<);
    ;
}

3469 [POI2008]BLO-Blockade的更多相关文章

  1. 割点判断+luogu 3469 POI2008 BLO

    1.根节点,有2棵及以上子树 2.非根节点,有子节点dfn[u]<=low[v] #include <bits/stdc++.h> #define N 1000050 using n ...

  2. BZOJ 1123: [POI2008]BLO

    1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1030  Solved: 440[Submit][Status] ...

  3. BZOJ1123: [POI2008]BLO

    1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 614  Solved: 235[Submit][Status] ...

  4. BZOJ 1123: [POI2008]BLO( tarjan )

    tarjan找割点..不是割点答案就是(N-1)*2, 是割点的话就在tarjan的时候顺便统计一下 ------------------------------------------------- ...

  5. bzoj 1123 [POI2008]BLO Tarjan求割点

    [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1540  Solved: 711[Submit][Status][Discu ...

  6. [POI2008]BLO(Tarjan)

    [POI2008]BLO Description Byteotia城市有\(n\)个 towns \(m\)条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所 ...

  7. 【dfs+连通分量】Bzoj1123 POI2008 BLO

    Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. 所有towns连通. Input 输入n&l ...

  8. BZOJ1123或洛谷3469 [POI2008]BLO-Blockade

    BZOJ原题链接 洛谷原题链接 若第\(i\)个点不是割点,那么只有这个点单独形成一个连通块,其它点依旧连通,则答案为\(2\times (n-1)\). 若第\(i\)个点是割点,那么去掉这个点相关 ...

  9. [POI2008] BLO

    link 试题分析 分两种情况考虑. 当此点不是割点是,答案是$2\times (n-1)$. 当是割点时,我们发现这个点把树分成了若干个联通块,只要两两相乘即可. #include<iostr ...

随机推荐

  1. 【译】OpenStack Heat基础介绍

    原文:http://blog.scottlowe.org/2014/05/01/an-introduction-to-openstack-heat/ 本文将简要地介绍OpenStack Heat. H ...

  2. 一个简单的139邮箱登录脚本--->java-selenium

    import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebE ...

  3. 洛谷 U10206 Cx的治疗

    题目背景 「Cx的故事」众所周知,Cx是一个宇宙大犇.由于Cx在空中花园失足摔下,导致他那蕴含着无穷智慧的大脑受到了严重的损伤,许多的脑神经断裂.于是,Cx的wife(有么?)决定请巴比伦最好的医师治 ...

  4. codeforces 235 B lets play osu!

    cf235B 一道有意思的题.(据说是美少女(伪)计算机科学家出的,hh) 根据题目要求,就是求ni^2的和. 而n^2=n*(n-1)+n; n*(n-1)=C(n,2)*2: 所以∑ai^2=∑a ...

  5. xls表格 拼接字段 拼json =CONCAT("{ code:'",A2,"',","codeName: '",B2,"',","flag: '",C2,"'},")

    xls表格 拼接字段 拼json =CONCAT("{ code:'",A2,"',","codeName: '",B2,"',& ...

  6. vue render {} 对象 说明文档

    Vue学习笔记进阶篇——Render函数 http://www.mamicode.com/info-detail-1906336.html 深入data object参数 有一件事要注意:正如在模板语 ...

  7. C++ 类中的static成员的初始化和特点

    C++ 类中的static成员的初始化和特点 #include <iostream> using namespace std; class Test { public: Test() : ...

  8. python常用模块之random

    random模块 import random print(random.random())#(0,1)----float 大于0且小于1之间的小数 print(random.randint(1,3)) ...

  9. 简单批处理命令直接启动你的AVD

    大家都知道,要想启动AVD,一般方法是先打开Android SDK and AVDmanager,再选择你要启动的AVD选择start(废话) 那么,有没有一种简单的方法在任何位置一键启动你指定的av ...

  10. docker部署xxl-job

    资源 xxl-job:1.9.1 docker:17.05.0-ce maven:3.5.0-jdk-8 tomcat:8.5.23.0 mysql:5.6.40 一.创建数据库 克隆项目到服务器下 ...