【CS Round #37 (Div. 2 only) D】Reconstruct Graph
【Link】:https://csacademy.com/contest/round-37/task/reconstruct-graph/statement/
【Description】
给你一张图;
包含n个点;m条边;
你可以在这张图的基础上添加边(不能有重边和自环);
使得节点1到节点i的最短距离为d[i]
问你可能的图的个数;
【Solution】
对于某一个节点x;
它只能和d的值为d[x]-1或者d[x]的节点直接相连
因为,d的值相同的x和y,如果它们俩之间连一条边的话,它们到节点1的距离是不会变的;
而每个节点x;
它必然要和一个d值为d[x]-1的点相连;
不然,就不能得到x的d值为d[x]了;
x节点是不能和d值小于d[x]-1的点相连的,因为那样x的d值就会小于d[x];
这样;
对于x,考虑每一个d值为d[x]-1的点,(设总数为cnt),要么和它连,要么不连;
如果原图上,x和d值为d[x]-1的点,没有一个点相连,那么就要去除全都不连的情况,不然就错了,所以乘上2cnt−1
如果原图上,x和d值为d[x]-1的点,有temp个已经相连了;(temp>0)
则乘上2cnt−temp
然后,d的值相同的点之间,可以任意相连;
设d值为i的节点个数为bo[i],然后他们之间在原图上已经有temp条边;
则答案乘上2(bo[i]∗(bo[i]−1)2−temp)
即每条边也都能选择连或不连
之后,考虑无解的情况;
如果d[i]出现了,而d[i]-1却没出现;
那么就无解;
如果d的值为0的点的个数大于1个,则无解;
如果原图上的一条边x->y
1<|d[x]−d[y]|
则也无解
【NumberOf WA】
1
【Reviw】
构造题,一般有明显的结论的;
没多想,就跳过了;
【Code】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5;
const LL MOD = 1e9+7;
int n,m,d[N+10],bo[N+10],num_edge[N+10],ma = 0;
vector <int> g[N+10];
bool wujie(){
rep1(i,1,n)
{
int len = g[i].size();
rep1(j,0,len-1){
int y = g[i][j];
if ( abs(d[y]-d[i])>1) return true;
}
}
rep1(i,1,n) {
bo[d[i]]++;
ma = max(ma,d[i]);
}
rep1(i,0,ma)
if (!bo[i]) return true;
if (bo[0]>1) return true;
return false;
}
LL Pow(LL x,LL y){
LL temp = 1;
while (y){
if (y&1){
temp = (temp*x)%MOD;
}
x = (x*x)%MOD;
y>>=1;
}
return temp;
}
int main(){
//Open();
//Close();
scanf("%d%d",&n,&m);
rep1(i,1,n)
scanf("%d",&d[i]);
rep1(i,1,m){
int x,y;
scanf("%d%d",&x,&y);
g[x].pb(y);
g[y].pb(x);
}
if (wujie()) {
printf("0\n");
return 0;
}
//计算同层内的边有多少条,顺便计算可能方案;
rep1(i,1,n){
int len = g[i].size();
rep1(j,0,len-1){
int y = g[i][j];
if (i < y && d[i]==d[y]){
num_edge[d[i]]++;
}
}
}
LL ans = 1;
//计算和d[i]-1层的点有多少条边,顺便计算可能方案;
rep1(i,1,n)
if (i!=1){
int len = g[i].size(),temp = 0;
rep1(j,0,len-1){
int y = g[i][j];
if (d[y] == d[i]-1){
temp++;
}
}
int remain = bo[d[i]-1]-temp;
if (temp==0){
ans = ans*(Pow(2,remain)-1)%MOD;
}else{
ans = ans*Pow(2,remain)%MOD;
}
}
//计算每一层可以连的边
rep1(i,0,ma){
ans = ans*Pow(2,1LL*bo[i]*(bo[i]-1)/2 - num_edge[i])%MOD;
}
printf("%lld\n",ans);
return 0;
}
/*
写完之后,明确每一步的作用
*/
【CS Round #37 (Div. 2 only) D】Reconstruct Graph的更多相关文章
- 【CS Round #37 (Div. 2 only) B】Group Split
[Link]:https://csacademy.com/contest/round-37/task/group-split/ [Description] 让你把一个数分成两个数a.b的和; (a,b ...
- 【CS Round #37 (Div. 2 only) A】Boring Number
[Link]:https://csacademy.com/contest/round-37/task/boring-number/ [Description] 让你找离平均数最近的一个数的下标; [S ...
- 【CS Round #39 (Div. 2 only) C】Reconstruct Sum
[Link]:https://csacademy.com/contest/round-39/task/reconstruct-sum/ [Description] 给你一个数字S; 让你找有多少对A, ...
- 【CS Round #36 (Div. 2 only) A】Bicycle Rental
[题目链接]:https://csacademy.com/contest/round-36/task/bicycle-rental/ [题意] 让你从n辆车中选一辆车; 每一辆车有3个属性 1.到达车 ...
- 【CS Round #39 (Div. 2 only) D】Seven-segment Display
[Link]:https://csacademy.com/contest/round-39/task/seven-segment-display/ [Description] 0..9各自有一个数字, ...
- 【CS Round #39 (Div. 2 only) B】Circle Elimination
[Link]:https://csacademy.com/contest/round-39/task/circle-elimination/ [Description] [Solution] 把n个点 ...
- 【CS Round #39 (Div. 2 only) A】Removed Pages
[Link]: [Description] [Solution] 每读入一个x; 把a[(x-1)/2]置为1即可; 统计1的个数 [NumberOf WA] [Reviw] [Code] /* */ ...
- 【CS Round #46 (Div. 1.5) E】Ultimate Orbs
[链接]链接 [题意] n个人从左到右站在一条直线上.每个人都有一个能力值g[i],然后每个人可以将相邻的一个人打败. 然后它的能力值能够增加相应的能力值(就是打败了的那个人的能力值). A能够打败B ...
- 【CS Round #46 (Div. 1.5) C】Set Subtraction
[链接]h在这里写链接 [题意] 一开始有n个数字,然后有一个数字X,把每个数字都减去X,又生成N个新的数字. 然后把这2*N个数字混在一起. 告诉你这2*N个数字是什么.让你复原出原来的N个数字,以 ...
随机推荐
- lua实现大数运算
lua实现的大数运算,代码超短,眼下仅仅实现的加减乘运算 ------------------------------------------------ --name: bigInt --creat ...
- Android 流量分析 tcpdump & wireshark
APP竞争已经白热化了,控制好自己Android应用的流量能够给用户一个良好的用户体验噢,给用户多一个不卸载的理由. Android 怎样进行流量分析?用好tcpdump & wireshar ...
- linux内核设计的艺术--系统启动第一步
计算机究竟是如何执行起来的呢,在我学习计算机的时候一直不是非常明确,可是近期借了本<linux内核设计的艺术>算是知道了计算机从按开机到启动操作系统之间究竟做了些什么. 这本书刚開始介绍的 ...
- linq replace with single call to FirstOrDefault 解决使用resharper产生的警告
使用resharper时对linq使用的FirstOrDefault 一直产生一个警告, 解决办法: 参考The Linq FirstOrDefault() Method and Null Resul ...
- dedecms后台登录,与后台界面去除多于的样式
http://jingyan.baidu.com/article/597035520f4edc8fc00740f7.html
- c# 值类型 之枚举
1声明枚举(enum)类型的变量 enum 变量名 { //标识符列表中,元素与元素之间用 , 逗号分隔: 标识符列表 } 枚举列表中的每个符号代表一个整数值,一个比他前面符号大的整数值,默认情况下, ...
- @synchronized 再考察
核心是:将标示对象与锁建立关联. 线程 锁 标识: 异常: NSString *test = @"test"; @try { // Allocates a lock for ...
- JavaScript:理解事件循环
话说js是单线程的,它通过浏览器事件循环轮询事件队列,来实现异步.然而,事件循环的时机是什么时候?浏览器是如何帮助JS引擎线程实现异步的? 浏览器页面进程的四个线程 首先说一下,chrome会为每一个 ...
- How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘
个人总结:读完这篇文章需要15分钟,文章主要讲解了Babel和TypeScript的工作原理,(例如对es6 类的转换,是将原始es6代码转换为es5代码,这些代码中包含着类似于 _classCall ...
- 【Henu ACM Round#16 E】Paths and Trees
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 感觉很像一道最短路. 然后就试了一发. 结果真的是.. 只要用一个优先队列优化的dijkstra算法求出每个点的最短路上的前一个点是 ...