CDQZ Day2
模拟题 day2
出题人: liu_runda
题目名称 一盘大棋 下一代互联网 强连通分量
源程序文件名 chess.cpp net.cpp scc.cpp
输入文件名 chess.in net.in scc.in
输出文件名 chess.out net.out scc.out
每个测试点时限 1s 1s 1s
内存限制 512MB 512MB 512MB
测试点数目 10 10 10
每个测试点分值 10 10 10
是否打开O2 优化 是 是 是
在windows 下用lemon 进行测试.
一盘大棋(chess)
【题目描述】
给出一个R*C 的棋盘.共有R 行C 列,R*C 个格子.现要在每个格子都填一个非
负整数.使得任意一个2*2 的正方形区域都满足这样的性质:左上角的数字+右下
角的数字=左下角的数字+右上角的数字.有些格子已经确定,你不能更改其中的
数字.其他格子的数字由你决定.下面是一个符合要求的3*3 的棋盘:
1 2 3
2 3 4
4 5 6
不难验证每个2*2 的区域都是符合要求的.
liu_runda 准备下一盘大棋,为此,他想要知道一个可行的填充棋盘的方案.但是
这个方案可能很大.所以你只需对给定的棋盘判定是否存在至少一种可行的填充
棋盘的方案.
【输入格式】
第一行输入一个T,表示数据组数。接下来T 组数据。
每组数据的第1 行3 个整数R,C,n,R 和C 表示棋盘的大小. n 表示已经被填好
数字的格子的数目
接下来n 行每行3 个整数ri,ci,ai,表示第ri 行ci 列的格子被填上了数字ai.
【输出格式】
T 行.第i 行是第i 组数据的答案.有合法方案时输出一行Yes,没有时输出一行
No.
【样例输入】
6
2 2 3
1 1 0
1 2 10
2 1 20
2 3 5
1 1 0
1 2 10
1 3 20
2 1 30
2 3 40
2 2 3
1 1 20
1 2 10
2 1 0
3 3 4
1 1 0
1 3 10
3 1 10
3 3 20
2 2 4
1 1 0
1 2 10
2 1 30
2 2 20
1 1 1
1 1 -1
【样例输出】
Yes
No
No
Yes
No
No
【数据范围】
第1 个测试点,R=1
第2,3 个测试点,R*C<=12,如果有解,保证存在一个解使得所有数字大小不超过2
第4,5 个测试点,R=2
第6,7 个测试点,R=3
第8 个测试点,1<=R,C<=20
第9 个测试点,1<=R,C<=100
对于全部测试点,1<=T<=6,1<=R,C,n<=100000,1<=ri<=R,1<=ci<=C,同一个格子不
会多次被填上数字.ai 是整数且绝对值不超过10^9.
下一代互联网(net)
【题目描述】
下一代互联网,基于IPv6 架构,很有可能改变互联网世界.然而这个题和IPv6 并没有
什么关系.起成这个名字,是因为liu_runda 在铺网线的时候希望下一代互联网早点出现.
现在给出一个a*b 的金属网格.你有两种网线:长度为1 的,和长度为根号2 的.长度为
1 的网线只能让你连接一个交叉点和它上下左右方向的交叉点,长度为根号2 的网线只
能让你连接一个交叉点和它斜对角方向的交叉点.
在这个金属网格上,有n 个坐标放置了路由器.现在希望用网线把这n 个路由器连接
起来.具体来说,你可以从一个路由器出发,连接若干条首尾相接的长度为1 或根号2 的网
线到达另一个路由器,那么这两个路由器就被连通了.中间不能分叉,必须一直到达另一个
路由器.从一个路由器可以引出多根网线.我们希望最终任意两个路由器直接或者间接连
通.
我们希望铺设网络消耗的网线尽量少.liu_runda 首先发现,要连接两个横纵坐标都不
同的路由器,先尽量使用长度为根号2 的网线,可以减少使用网线的根数和总长度,所以他
规定任意一对直接连接的路由器,在连接这一对路由器使用网线长度最小的前提下,都必
须尽可能使用长度为根号2 的网线.
接下来liu_runda 发现,长度为根号2 的网线比长度为1 的网线贵得多…但是liu_runda
并不想收回他的规定.现在,他只能在已经有的辣鸡规定下,合理地选择哪几对路由器进行
连接,尽量减少长度根号2 的网线的使用数目.(即使这样的方案下网线的总长度不一定最
短)请问他最少需要使用多少根长度为根号2 的网线?
【输入格式】
第一行三个数字a,b,n 分别表示行数(路由器的纵坐标范围),列数(路由器的横坐标范
围)和路由器的数目.
接下来n 行,第i 行两个数字x[i],y[i]依次表示第i 个路由器的横坐标和纵坐标
【输出格式】
一行一个整数,表示liu_runda 至少需要使用的长度为根号2 的网线数目.
【样例输入】
【样例输出】
【数据范围】
第1 个测试点,n=2
第2 个测试点,n=3
第3,4,5,6 个测试点,n<=500,0<a,b <=105
所有数据,n<=105,0<a,b<=109,0<y[i]<=a,0<x[i]<=b.不会出现横纵坐标相同的两个路由
器.
强连通分量(scc)
【题目描述】
给出一张有向图,统计图中有多少个强联通分量,并从大到小依次输出每个强连通分
量的大小.
【输入格式】
第一行两个整数n,m 表示点数和边数
接下来m 行每行两个数字u,v 表示从u 到v 有一条有向边.
第一行一个整数c 表示强连通分量的个数
第二行c 个整数,空格隔开,从大到小依次表示每个强连通分量包含的点数.
【样例输入】
3 3
1 2
2 1
1 3
【样例输出】
2
2 1
【数据范围】
第1,2,3 个测试点,所有强连通分量大小不超过2
第4,5,6 个测试点,n<=10,m<=20
不会有自环,但可能有重复的边.
所有的测试数据,n<=105,m<=5*105
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cassert> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=100005; 7 typedef long long ll; 8 int ufs[maxn];ll w1[maxn]; 9 int R,C; 10 struct node{ 11 int x,y,val; 12 void read(){ 13 scanf("%d%d%d",&x,&y,&val); 14 assert(1<=x&&x<=R&&1<=y&&y<=C); 15 } 16 }P[maxn]; 17 bool cmpx(const node &A,const node &B){ 18 return A.x<B.x; 19 } 20 bool cmpy(const node &A,const node &B){ 21 return A.y<B.y; 22 } 23 int find(int x){ 24 if(x==ufs[x])return x; 25 int rt=find(ufs[x]); 26 w1[x]+=w1[ufs[x]]; 27 return ufs[x]=rt; 28 } 29 bool link(int a,int b,ll w){ 30 if(find(a)!=find(b)){ 31 int ra=find(a),rb=find(b); 32 ufs[ra]=ufs[rb]; 33 w1[ra]=w+w1[b]-w1[a]; 34 return true; 35 }else{ 36 return w1[a]==w+w1[b]; 37 } 38 } 39 ll Min1[maxn],Min2[maxn]; 40 int main(){ 41 freopen("chess.in","r",stdin); 42 freopen("chess.out","w",stdout); 43 int tests;scanf("%d",&tests); 44 while(tests--){ 45 bool flag=true; 46 scanf("%d%d",&R,&C); 47 for(int i=1;i<=R;++i){ 48 ufs[i]=i;w1[i]=0; 49 } 50 int n;scanf("%d",&n); 51 for(int i=1;i<=n;++i)P[i].read(); 52 for(int i=1;i<=n;++i)if(P[i].val<0)flag=false; 53 54 sort(P+1,P+n+1,cmpy); 55 for(int i=1;i<n;++i) 56 if(P[i].y==P[i+1].y) 57 if(!link(P[i].x,P[i+1].x,P[i+1].val-P[i].val))flag=false; 58 59 memset(Min1,0x3f,sizeof(Min1)); 60 memset(Min2,0x3f,sizeof(Min2)); 61 for(int i=1;i<=n;++i){ 62 int rt=find(P[i].x); 63 Min1[rt]=min(Min1[rt],P[i].val+w1[P[i].x]); 64 } 65 for(int i=1;i<=R;++i){ 66 int rt=find(i); 67 Min2[rt]=min(Min2[rt],-w1[i]); 68 } 69 for(int i=1;i<=R;++i) 70 if(ufs[i]==i&&Min1[i]+Min2[i]<0)flag=false; 71 printf("%s\n",flag?"Yes":"No"); 72 } 73 return 0; 74 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=100005; 5 int ufs[maxn]; 6 int find(int x){ 7 return (x==ufs[x])?ufs[x]:(ufs[x]=find(ufs[x])); 8 } 9 struct point{ 10 int x,y,num; 11 }P[maxn]; 12 bool cmpx(const point &A,const point &B){ 13 return A.x<B.x; 14 } 15 bool cmpy(const point &A,const point &B){ 16 return A.y<B.y; 17 } 18 struct edge{ 19 int u,v,w; 20 edge(int a=0,int b=0,int c=0){ 21 u=a;v=b;w=c; 22 } 23 bool operator <(const edge &B)const{ 24 return w<B.w; 25 } 26 }E[maxn*2];int tot=0; 27 int main(){ 28 freopen("net.in","r",stdin); 29 freopen("net.out","w",stdout); 30 int n; 31 scanf("%*d%*d%d",&n); 32 for(int i=1;i<=n;++i){ 33 scanf("%d%d",&P[i].x,&P[i].y); 34 P[i].num=i; 35 } 36 sort(P+1,P+n+1,cmpx); 37 for(int i=1;i<n;++i){ 38 E[++tot]=edge(P[i].num,P[i+1].num,P[i+1].x-P[i].x); 39 } 40 sort(P+1,P+n+1,cmpy); 41 for(int i=1;i<n;++i){ 42 E[++tot]=edge(P[i].num,P[i+1].num,P[i+1].y-P[i].y); 43 } 44 sort(E+1,E+tot+1); 45 for(int i=1;i<=n;++i)ufs[i]=i; 46 int ans=0; 47 for(int i=1;i<=tot;++i){ 48 if(find(E[i].u)!=find(E[i].v))ufs[find(E[i].u)]=find(E[i].v),ans+=E[i].w; 49 } 50 printf("%d\n",ans); 51 return 0; 52 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=100005; 6 vector<int> to[maxn]; 7 int n,m; 8 int dfn[maxn],low[maxn],T; 9 int stk[maxn],top;bool ins[maxn]; 10 int sz[maxn],tot; 11 void dfs(int x){ 12 dfn[x]=low[x]=++T; 13 ins[x]=true;stk[++top]=x; 14 for(vector<int>::iterator pt=to[x].begin();pt!=to[x].end();++pt){ 15 if(!dfn[*pt]){ 16 dfs(*pt); 17 if(low[*pt]<low[x])low[x]=low[*pt]; 18 }else{ 19 if(ins[*pt]&&dfn[*pt]<low[x])low[x]=dfn[*pt]; 20 } 21 } 22 if(low[x]==dfn[x]){ 23 ++tot; 24 do{ 25 //printf("%d ",stk[top]); 26 sz[tot]++;ins[stk[top]]=false;--top; 27 }while(stk[top+1]!=x); 28 //printf("\n"); 29 } 30 } 31 int main(){ 32 freopen("scc.in","r",stdin); 33 freopen("scc.out","w",stdout); 34 scanf("%d%d",&n,&m); 35 int u,v; 36 for(int i=1;i<=m;++i){ 37 scanf("%d%d",&u,&v); 38 to[u].push_back(v); 39 } 40 for(int i=1;i<=n;++i)if(!dfn[i])dfs(i); 41 sort(sz+1,sz+tot+1); 42 printf("%d\n",tot); 43 for(int i=tot;i>=1;--i)printf("%d%c",sz[i],(i==1)?'\n':' '); 44 return 0; 45 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<ctime> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #define R(a,b,c) for(register int (a)=(b);(a)<=(c);++(a)) 9 #define nR(a,b,c) for(register int (a)=(b);(a)>=(c);--(a)) 10 #define Ii inline int 11 #define Il inline long long 12 #define Iv inline void 13 #define Id inline double 14 #define ll long long 15 #define re register 16 #define Cmax(a,b) ((a)=(a)>(b)?(a):(b)) 17 #define Cmin(a,b) ((a)=(a)<(b)?(a):(b)) 18 #define D_e(x) printf("&_____%d______&",x); 19 #define D_e_Line printf("\n-----------------\n"); 20 #define Pause system(pause) 21 using namespace std; 22 const int N=100001; 23 const int M=500001; 24 Ii read(){ 25 int s=0,f=1;char c; 26 for(c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1; 27 while(c>='0'&&c<='9')s=s*10+(c^'0'),c=getchar(); 28 return s*f; 29 } 30 Iv print(int x){ 31 if(x<0)putchar('-'),x=-x; 32 if(x>9)print(x/10); 33 putchar(x%10^'0'); 34 } 35 struct node{ 36 int nxt,pre; 37 }e[M]; 38 int id,color,head[M],cnt,dfn[N],low[N],vis[N],col[N],siz[N]; 39 stack<int>sta; 40 Iv add(int u,int v){ 41 e[++cnt]=(node){head[u],v},head[u]=cnt; 42 } 43 Iv Tarjan(int u){ 44 dfn[u]=low[u]=++id; 45 sta.push(u),vis[u]=1; 46 for(re int i=head[u];i;i=e[i].nxt){ 47 int v=e[i].pre; 48 if(!dfn[v]) 49 Tarjan(v),Cmin(low[u],low[v]); 50 else if(vis[v]) 51 Cmin(low[u],dfn[v]);/////// 52 } 53 if(low[u]==dfn[u]){ 54 ++color; 55 int now=-1; 56 while(now!=u){ 57 now=sta.top(),sta.pop(), 58 col[now]=color, 59 ++siz[color], 60 vis[now]=0; 61 } 62 } 63 } 64 //#define DEBUG ; 65 int main(){ 66 freopen("scc.in","r",stdin),freopen("scc.out","w",stdout); 67 int n=read(),m=read(); 68 R(i,1,m){ 69 int u=read(),v=read(); 70 //for(re int i=head[u];i;i=e[i].nxt) 71 // if(e[i].pre==v) 72 // continue; 73 add(u,v); 74 } 75 R(i,1,n) 76 if(!dfn[i]) 77 Tarjan(i); 78 sort(siz+1,siz+color+1); 79 print(color),putchar('\n'); 80 nR(i,color,1) 81 printf("%d ",siz[i]); 82 #ifdef DEBUG 83 putchar('\n'); 84 R(i,1,n) 85 printf("%d-> %d\n",i,col[i]); 86 #endif 87 return 0; 88 } 89 /* 90 6 6 91 1 4 92 1 2 93 2 5 94 1 5 95 1 3 96 3 6 97 98 6 6 99 1 4 100 1 2 101 2 5 102 5 1 103 1 3 104 3 6 105 106 3 4 107 1 2 108 1 2 109 2 3 110 3 1 111 112 5 5 113 1 2 114 2 3 115 3 1 116 1 5 117 4 1 118 119 3 3 120 1 2 121 2 3 122 3 1 123 */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<ctime> 5 #include<algorithm> 6 #include<cmath> 7 //#include<stack> 8 #define R(a,b,c) for(register int (a)=(b);(a)<=(c);++(a)) 9 #define nR(a,b,c) for(register int (a)=(b);(a)>=(c);--(a)) 10 #define Ii inline int 11 #define Il inline long long 12 #define Iv inline void 13 #define Id inline double 14 #define Ib inline bool 15 #define ll long long 16 #define re register 17 #define Fill(a,b) memset((a),(b),sizeof((a))) 18 #define Cmax(a,b) ((a)=(a)>(b)?(a):(b)) 19 #define Cmin(a,b) ((a)=(a)<(b)?(a):(b)) 20 #define D_e(x) printf("&_____%d______&",x); 21 #define D_e_Line printf("\n-----------------\n"); 22 #define aause system("pause") 23 using namespace std; 24 const int N=100001; 25 //const int M=500001; 26 Ii read(){ 27 int s=0,f=1;char c; 28 for(c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1; 29 while(c>='0'&&c<='9')s=s*10+(c^'0'),c=getchar(); 30 return s*f; 31 } 32 Iv print(int x){ 33 if(x<0)putchar('-'),x=-x; 34 if(x>9)print(x/10); 35 putchar(x%10^'0'); 36 } 37 int fa[N]; 38 int Find(int x){ 39 return x==fa[x]?fa[x]:fa[x]=Find(fa[x]); 40 } 41 struct node{ 42 int x,y,id; 43 }a[N]; 44 bool cmp_x(const node &a,const node &b){ 45 return a.x<b.x; 46 } 47 bool cmp_y(const node &a,const node &b){ 48 return a.y<b.y; 49 } 50 struct edge{ 51 int l,r,w; 52 bool operator <(const edge &b)const{ 53 return w<b.w; 54 } 55 }e[N<<1];int cnt; 56 int main(){ 57 freopen("net.in","r",stdin),freopen("net.out","w",stdout); 58 read(),read(); 59 int n=read(); 60 R(i,1,n) 61 a[i]=(node){read(),read(),i}, 62 fa[i]=i; 63 sort(a+1,a+n+1,cmp_x); 64 R(i,1,n-1) 65 e[++cnt]=(edge){a[i].id,a[i+1].id,a[i+1].x-a[i].x}; 66 sort(a+1,a+n+1,cmp_y); 67 R(i,1,n-1) 68 e[++cnt]=(edge){a[i].id,a[i+1].id,a[i+1].y-a[i].y}; 69 sort(e+1,e+cnt+1); 70 int ans=0; 71 R(i,1,cnt){ 72 int p=Find(e[i].l),q=Find(e[i].r); 73 if(p!=q) 74 fa[p]=q, 75 ans+=e[i].w; 76 } 77 print(ans); 78 return 0; 79 }