【icpc网络赛大连赛区】Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2487 Accepted Submission(s): 386
a graph G is
a graph H on
the same vertices such that two distinct vertices of H are
adjacent if and only if they are notadjacent
in G.
Now you are given an undirected graph G of N nodes
and M bidirectional
edges of unit length.
Consider the complement of G,
i.e., H.
For a given vertex S on H,
you are required to compute the shortest distances from S to
all N−1 other
vertices.
the number of test cases. For each test case, the first line contains two integers N(2≤N≤200000) and M(0≤M≤20000).
The following M lines
each contains two distinct integers u,v(1≤u,v≤N) denoting
an edge. And S (1≤S≤N) is
given on the last line.
cases, print a single line consisting of N−1 space
separated integers, denoting shortest distances of the remaining N−1 vertices
from S (if
a vertex cannot be reached from S, output ``-1" (without quotes) instead) in ascending order of vertex number.
1
2 0
1
1
【题解】
补图:
在完全图的基础上,把我们在这题中输入的边给去掉。剩余的图就是输入的图的补图。然后可以理解为,原来出现过的边在补图中都不会出现了。
在补图上做最短路。(边权为单位长度)
这题需要分两种情况来做。
1.
m<n-1;
则我们输入的图肯定是不连通的图。因为少于n-1条边你没办法使一张图连通.
这个时候节点的数量可能达到20万。你不可能写34组的dijkstra..而且每组都20万。
然后我们就有特殊的技巧了。
这是一种情况。
可以看到边的数目小于n-1条。
然后我们考虑一下它的补图,因为有一个点肯定是和所有的其他点都没有联通的。在这里就是4号节点。那么我把它和其他的点都连上,如下图
但是注意我还没有把其他边连上。这还不是它的补图。
但我们却由此得到一个思路。那就是所有的点都可以经过4号节点再多走一步到达其他任意一个节点。也就是说花费最多是2.
那有哪一些点到其他点的花费是1呢?
就是那些一开始在原图上没有和起点直接相连的点
假设起点是3.
那么完整的补图会是这样的
可以看到,原图上未和3号节点直接相连的节点与3的距离都是1.
这是因为。如果3号节点一开始没有和任何节点相连。那么补图上。
3号节点是会和其他所有节点都连上一条边的,也就是距离为1
但是如果有节点和3号节点相连。那么在补图上就不能存在一条边由3号节点直接指向那个节点了(即不存在距离为1的代价直接从3号节点到达那个点)
而我们刚才的分析已经得到最大的代价为2,即把那个一开始谁都没连过的节点作为中间节点走两步到达目标。
而m < n-1保证了有那样一个一开始谁都没连过的节点。
2.
m>=n-1;
这下你可说不准图有没有联通了。那该怎么办呢?
注意到n<=m+1.而m最大为20000;实际上我们已经可以用dijkstra来解决这个问题了。
这是它的能力范围之内的事情了。
从起点开始进行dijkstra算法就可以了。
详细的过程看代码注释。
题目的数据显示在n-1<=m的时候n最大值没有超过6000;
【代码】
#include <cstdio>
#include <cstring> int T,n,m,bian[25000][2],s,dis[5500+100],w[6000][6000];
bool linjin[200001+100],haved[5500+100]; const int MAX_N = 2100000000/3;//这是给dis数组一开始赋值用的玩意,就是一个很大的值。 void input_data()
{
scanf("%d%d",&n,&m);//输入n个点m条边。
for (int i = 1;i <= m;i++)//输入m条边。
scanf("%d%d",&bian[i][0],&bian[i][1]);
scanf("%d",&s);//输入起点。
} void get_ans()
{
if (m < n-1) //如果这张原图是不可能联通的。
{
for (int i = 1;i <= m;i++)//看下有没有和起点相连的点。
{
if (bian[i][0] == s)
linjin[bian[i][1]] = true;//如果和起点相连那么从起点到它的最短距离就只能是2
if (bian[i][1] == s)
linjin[bian[i][0]] = true;
}
bool flag = false;//这个flag用来判断要不要输出空格。
for (int i = 1;i <= n;i++)
if (i!=s)//如果不是起点,就要输出一些东西了
{
if (flag)
printf(" ");
if (linjin[i])
printf("2");//如果这个点和起点相连。则最短的距离只能是2
else
printf("1");//如果不和起点相连。那么就可以存在一条边直接从起点指向该点。
flag = true;//判断已经输出过一个答案。下次要输出空格了。
}
printf("\n");//输出一个空行
}
else //n <= m-1的情况
{//在这个情况下n的最大值不超过5500;(数据显示)
for (int i = 1;i <= n;i++)
for (int j = 1;j <= n;j++)//一开始先构造出一个完全图。
if (i!=j)
w[i][j] = 1;//任意两点之间的距离除了两个相同的点的距离外都为1.
else
w[i][j] = 0;
for (int i = 1;i <= m;i++) //然后输入的边是原图的边,它在补图里面就是不存在的了。
{
w[bian[i][0]][bian[i][1]] = MAX_N;//置为一个很大的数就可以了。
w[bian[i][1]][bian[i][0]] = MAX_N;
}
for (int i = 1;i <= n;i++)//先置起点到所有的点的距离为起点到该点的距离。
{
dis[i] = w[s][i];
haved[i] = false;//置该点还不是最短距离。
}
haved[s] = true;//起点到起点已经是最短距离了。
for (int i = 1;i <= n;i++)
{
int k = -1,min = MAX_N;
for (int j = 1;j <= n;j++)//找到离起点最近的点。(且要求它之前没有别用来更新过。)
if (!haved[j] && dis[j] < min)
{
min = dis[j];
k = j;
}
if (k == -1)//如果没找到就说明全部找完直接结束
break;
haved[k] = true;//否则就标记这个节点已经被用来更新过了。下次就不会再用到它了。
for (int j = 1;j <= n;j++) //如果之前没有用过这个点更新,且需要更新
if (!haved[j] && (dis[j] > dis[k] + w[k][j]))
dis[j] = dis[k] + w[k][j];//则更新
}
bool flag = false;//flag依旧是用来控制输出的。
for (int i = 1;i <= n;i++)
if (i!=s)
{
if (flag) printf(" ");//如果之前已经输出过一个了,则需要输出一个空格。
if (dis[i] >= MAX_N) //如果是一个“无穷大”的值就直接输出-1,否则输出最短路。
printf("-1");
else
printf("%d",dis[i]);
flag = true;//标记已经输出过答案。
}
printf("\n");
}
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
//freopen("F:\\rush_out.txt","w",stdout);
scanf("%d",&T);//输入T组数据。
while (T--)
{
memset(linjin,0,sizeof(linjin));
input_data();
get_ans();
}
return 0;
}
【icpc网络赛大连赛区】Sparse Graph的更多相关文章
- 【2018ACM/ICPC网络赛】沈阳赛区
这次网络赛没有打.生病了去医院了..尴尬.晚上回来才看了题补简单题. K Supreme Number 题目链接:https://nanti.jisuanke.com/t/31452 题意:输入一个 ...
- Ryuji doesn't want to study 2018徐州icpc网络赛 树状数组
Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, ea ...
- 【2018ACM/ICPC网络赛】焦作赛区
A Magic Mirror 题目链接:https://nanti.jisuanke.com/t/31710 题意:输入字符串,如果是“Jessy”就输出“Good Guy!",否则输出“D ...
- 【2018ACM/ICPC网络赛】徐州赛区
呃.自闭了自闭了.我才不会说我写D写到昏天黑地呢. I Characters with Hash 题目链接:https://nanti.jisuanke.com/t/31461 题意:给你一个字符串 ...
- Trace 2018徐州icpc网络赛 (二分)(树状数组)
Trace There's a beach in the first quadrant. And from time to time, there are sea waves. A wave ( xx ...
- Supreme Number 2018沈阳icpc网络赛 找规律
A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying ...
- Trace 2018徐州icpc网络赛 思维+二分
There's a beach in the first quadrant. And from time to time, there are sea waves. A wave ( xx , yy) ...
- Features Track 2018徐州icpc网络赛 思维
Morgana is learning computer vision, and he likes cats, too. One day he wants to find the cat moveme ...
- 2017 ICPC网络赛(西安)--- Xor
题目连接 Problem There is a tree with n nodes. For each node, there is an integer value ai, (1≤ai≤1,000 ...
随机推荐
- CISP/CISA 每日一题 11
CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...
- 洛谷 P3654 First Step (ファーストステップ)
洛谷 P3654 First Step (ファーストステップ) https://www.luogu.org/problemnew/show/P3654 题目描述 可是……这个篮球场,好像很久没有使用过 ...
- Detecting a return-oriented programming exploit
A method and apparatus for detecting a Return-Oriented Programming exploitation. At a computer devic ...
- 洛谷—— P1080 国王游戏
https://www.luogu.org/problem/show?pid=1080 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整 ...
- ArcGIS Engine 线段绘制
转自ArcGIS Engine 线段绘制研究 基本步骤 构建形状 1. 创建 IPoint IPoint m_Point = new PointClass(); m_Point.PutCoords(x ...
- java list 容器的ConcurrentModificationException
java中的很多容器在遍历的同时进行修改里面的元素都会ConcurrentModificationException,包括多线程情况和单线程的情况.多线程的情况就用说了,单线程出现这个异常一般是遍历( ...
- 116.C语言异常抛错
#include <stdlib.h> #include <stdio.h> #include <setjmp.h> //异常抛错检测 jmp_buf buf1; ...
- Oracle 12C R2 on Linux 7.X Data Guard 搭建文档
1.查看主机和数据库信息 [oracle@oracle1 ~]$ sqlplus / as sysdba SQL*Plus: Release 12.2.0.1.0 Production on ...
- 阿里云部署Docker(3)----指令学习
通过上两节的学习http://blog.csdn.net/minimicall/article/details/40119177 和http://blog.csdn.net/minimicall/ar ...
- js中#代表什么
js中#代表什么 一.总结 1.#号:代表id选择器 2. $('#div1'). : 常用用法,前面也有$符号 二."#"在js中代表什么 js里我不曾看到用到‘#’的代码端, ...