Explosion at Cafebazaar

时间限制: 1 Sec  内存限制: 128 MB

题目描述

You are an engineer at Cafebazaar and your specialty is understanding networks and their behaviors. Your colleagues have designed a network of n switches with m directed links that connect pairs of these switches. Each switch has a buffer where it stores the data and two modes, called sending mode and receiving mode. In the sending mode, a switch sends the data stored in its buffer to each of its outgoing links simultaneously and at the end clears its buffer. In the receiving mode,a switch concatenates the data from all its incoming links and stores them in its buffer, so at the end, the length of the data stored in its buffer is equal to the sum of the lengths of all the data on the incoming links. 
Assume that at time t = 0, all the switches are in sending mode and have an empty buffer except switch i which stores a 1-bit package of data in its buffer. Also, all the switches change their modes after each second, so at time t = 1 all the switches change to receiving mode, at time t = 2 they change to sending mode, and so on. Switch i is called explosive if the maximum length of data stored in the buffers of switches is not bounded as t goes to infinity. 
Your task is to calculate the number of explosive switches in the network.

输入

There are multiple test cases in the input. The first line of each test case contains two space-separated integers n and m,where n indicates the number of switches and m indicates the number of directed links (1 ⩽ n, m ⩽ 50, 000). Each of the next m lines contains two space-separated integers u, v where (u, v) indicates a directed link from switch u to switch v (1 ⩽ u, v ⩽ n, u≠v). The input terminates with a line containing 0 0 which should not be processed.

输出

For each test case, output a single line containing the number of explosive switches.

样例输入

3 3
1 2
2 3
3 1
5 6
1 2
2 3
3 1
3 4
4 5
5 3
4 5
1 2
2 3
3 2
3 2
3 4
0 0

样例输出

0
5
3

来源/分类

Tehran2016


题意:在n个点m条边的图中,每个点可以沿有向边发送数据,当然每个点也可以接收数据。每个点发送数据后,该点的数据就会清零,图中所有点发送和接收数据是同步的。(即它们一起发送数据,一起接收数据)。问在哪些点放上单位数据,可以使图中某些点的数据量达到无穷大。
分析:要使单位数据最后变成无穷大数据,首先要有环。首先考虑单个环使数据爆炸的情况。环中必须存在某一点,它的入度大于等于2,这个环才能无限扩充数据。其次如果是简单的n个点n条边的环,它虽然不能使数据量增大,但是它可以源源不断的产生数据和保留数据,所以如果一个简单环连接着另一个环,那么这个简单环上的点也可以使数据爆炸。最后,所有连向数据爆炸环的点都可以使数据爆炸。
做法:我的做法比较繁琐,我先求出了所有的环(强连通分量)并把环缩成点,再判一个环是否可以使数据爆炸,再判两个环是否可以使数据爆炸,最后反向跑dfs判连向爆炸环的点。
#include<bits/stdc++.h>
#define N 50050
using namespace std; int dfn[N],low[N],vis[N],color[N],now_clock,now_color;
int Stack[N],top;
vector<int>edges[N];
int explosive[N],du[N],sum_point[N],dfs2_vis[N],ans;
vector<int>newedges[N];
vector<int>edges2[N]; void init(int n)
{
for(int i=;i<=n;i++)edges[i].clear(),newedges[i].clear(),edges2[i].clear();
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(explosive,,sizeof(explosive));
memset(du,,sizeof(du));
memset(sum_point,,sizeof(sum_point));
memset(dfs2_vis,,sizeof(dfs2_vis));
now_clock=;
top=;
now_color=;
ans=; } void dfs(int x)
{
dfn[x]=low[x]=now_clock++;
vis[x]=;
Stack[++top]=x; int Size=edges[x].size();
for(int i=;i<Size;i++)
{
int v=edges[x][i];
if(!dfn[v])
{
dfs(v);
low[x]=min(low[x],low[v]);
}
else
if(vis[v])low[x]=min(low[x],dfn[v]);
} if(dfn[x]==low[x])
{
while(Stack[top]!=x)
{
vis[Stack[top]]=;
color[Stack[top]]=now_color;
top--;
} vis[Stack[top]]=;
color[Stack[top]]=now_color++;
top--;
}
} void dfs2(int x)
{
if(!dfs2_vis[x])
{
dfs2_vis[x]=;
ans+=sum_point[x];
} int Size=newedges[x].size();
for(int i=;i<Size;i++)
if(!dfs2_vis[newedges[x][i]])
dfs2(newedges[x][i]); } int dfs3(int x)
{
if(sum_point[x]>=)return ; int Size=edges2[x].size();
for(int i=;i<Size;i++)
if(dfs3(edges2[x][i]))return ; return ;
} int main()
{ int n,m;
while(scanf("%d %d",&n,&m)==)
{
if(!n)return ; init(n); while(m--)
{
int u,v;
scanf("%d %d",&u,&v);
edges[u].push_back(v);
} for(int i=;i<=n;i++)
if(!dfn[i])dfs(i); for(int i=;i<=n;i++)
{
int Size=edges[i].size();
for(int j=;j<Size;j++)
{
int u=i,v=edges[i][j];
if(color[u]==color[v])
du[v]++; }
} for(int i=;i<=n;i++)
{
sum_point[color[i]]++;
if(du[i]>=)explosive[color[i]]=;
}
/* for(int i=1;i<=n;i++)printf("%d ",color[i]);
printf("\n");
for(int i=1;i<now_color;i++)printf("%d ",sum_point[i]);
printf("\n");
for(int i=1;i<now_color;i++)printf("%d ",explosive[i]);
printf("\n");
*/
for(int i=;i<=n;i++)
{
int Size=edges[i].size();
for(int j=;j<Size;j++)
{
int u=i,v=edges[i][j];
if(color[u]!=color[v])
{
newedges[color[v]].push_back(color[u]);
edges2[color[u]].push_back(color[v]);
}
}
} for(int i=;i<now_color;i++)
if(!explosive[i]&&sum_point[i]>=)
{
int Size=edges2[i].size();
for(int j=;j<Size;j++)
if(dfs3(edges2[i][j]))
{
explosive[i]=;
break;
}
} for(int i=;i<now_color;i++)
if(explosive[i])dfs2(i); printf("%d\n",ans);
} return ;
}

Explosion at Cafebazaar的更多相关文章

  1. 2016 ACM ICPC Asia Region - Tehran

    2016 ACM ICPC Asia Region - Tehran A - Tax 题目描述:算税. solution 模拟. B - Key Maker 题目描述:给出\(n\)个序列,给定一个序 ...

  2. NBUT 1635 Explosion(最小顶点覆盖)

    [1635] Explosion 时间限制: 10000 ms 内存限制: 65535 K 问题描述 there is a country which contains n cities connec ...

  3. Codeforces Gym 191033 E. Explosion Exploit (记忆化搜索+状压)

    E. Explosion Exploit time limit per test 2.0 s memory limit per test 256 MB input standard input out ...

  4. 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp

    2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp [P ...

  5. upc组队赛3 Chaarshanbegaan at Cafebazaar

    Chaarshanbegaan at Cafebazaar 题目链接 http://icpc.upc.edu.cn/problem.php?cid=1618&pid=1 题目描述 Chaars ...

  6. hdu 5036 Explosion(概率期望+bitset)

    Problem Description Everyone knows Matt enjoys playing games very much. Now, he to N. Input The firs ...

  7. HDU - 5036 Explosion

    Problem Description Everyone knows Matt enjoys playing games very much. Now, he is playing such a ga ...

  8. hdu5306 Explosion

    题目链接 题意 有n个房间,每个房间里面有若干把钥匙,每把钥匙可以打开对应的一扇门.如果手中没有钥匙,就要随机轰炸一个房间来打开这个房间.如果有钥匙,就要去打开这些房间.问期望轰炸次数是多少. 思路 ...

  9. HDU 5036 Explosion (传递闭包+bitset优化)

    <题目链接> 题目大意: 一个人要打开或者用炸弹砸开所有的门,每个门后面有一些钥匙,一个钥匙对应一个门,告诉每个门里面有哪些门的钥匙.如果要打开所有的门,问需要用的炸弹数量为多少. 解题分 ...

随机推荐

  1. ubuntu 14.04 安装mysql,并配置远程连接和中文乱码

    1. 安装MySQL的jar root@computer-PowerEdge-T30:~# sudo apt-get install mysql-server mysql-client在本次安装中,根 ...

  2. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  3. 由DAG到背包问题——记忆化搜索和递推两种解法

    一.问题描述 物品无限的背包问题:有n种物品,每种均有无穷多个.第 i 种物品的体积为Vi,重量为Wi.选一些物品装到一个容量为 C 的背包中,求使得背包内物品总体积不超过C的前提下重量的最大值.1≤ ...

  4. HTML5微信播放全屏问题的解决方法

    在ios和安卓手机里的微信下播放视频时,会遇到不少问题,例如需要手动点击,视频才会播放,并且视频会跳出微信框,出现控制条,如果视频不是腾讯视频,播放完毕会出现腾讯视频的广告推送等问题 解决办法:给vi ...

  5. 读懂 Deployment YAML【转】

    既然要用 YAML 配置文件部署应用,现在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常类似. 还是以 nginx-deploymen ...

  6. Java生成固定长度的随机字符串(以大小写字母和数字)

    package org.jimmy.autosearch2019.test; import java.util.ArrayList; import java.util.Random; /** * @a ...

  7. C-基础:atoi

    C语言库函数名: atoi 功 能: 把字符串转换成整型数. 名字来源:ASCII to integer 的缩写. 原型: int atoi(const char *nptr); 函数说明: 参数np ...

  8. 005 String s = "Hello";s = s + " world!";执行这两行代码执行后,原始的 String 对象中的内容到底变了没有?

    原始的String对象中的内容没有改变成“Hello world”. 1.原因 因为在Java中String类被设计成不可改变的类,所以String类的所有对象都是不可变的.第一句代码中,s(存储在栈 ...

  9. 使用bat脚本调用py文件直接获取应用的包名和targetversion

    背景: 在上一篇已经介绍过如何利用python调用aapt获取包名 https://www.cnblogs.com/reseelei-despair/p/11078750.html 但是因为每次都要修 ...

  10. win10文件共享的实现

    1)启动网络发现 打开网络共享中心->更改高级共享设置->修改如下 2)如果需要其他客户端无密码访问        修改如下: 3)如果打算使用Guest访问  用户帐户->管理帐户 ...