【codechef】Computer Network(脑洞题)

题目描述

你的一门课的大作业要求你为学校机房设计一个计算机网络。

机房一共有 N 台计算机,而你一共需要建设 M 条链接,每条链接连接两台计算机。同时,网络还需要满足三个条件。

第一个条件是,网络中的每两台计算机都必须直接或者间接地相连。

可能会有人恶意攻击这个网络,因此第二个条件是,如果网络中任意一台机器因为一些原因而无法连接(即断开了与其他所有计算机的链接),剩余的计算机也应当能两两互连。换言之,对于网络中计算机的任意大小为 (N − 1) 的子集,第一个条件都应当成立。

第三个条件是,网络中不应有多余的链接。如果将一条链接移除后,上面的两个条件仍然满足,那么我们称这条链接是多余的。

给定 N 和 M,请构造一个满足上面三个条件的有 N 台计算机和 M 条链接的网络,或者指出问题无解。


输入格式

输入数据的第一行包含一个整数 T,代表数据组数。接下来是 T 组数据。每组数据仅有一行,包含两个整数 N 和 M,分别代表计算机和链接的数量。

输出格式

对于每组数据,如果问题无解,输出一行-1 -1。否则,输出 M 行,每行包含两个整数,代表一条链接所连接的两台计算机的编号。由于有第三个条件的存在,不允许出现重复的链接以及连向自身的链接。


好好感受一下这两幅图。。。明明已经发现了题目给的隐含条件(sub1:1<=n<=4,肯定<=4和>4是两种做法),然后画很久也画出点什么了(在图形内部画点可以增加总的边数,并且在图形内部画边必须至少隔两条外边,并且内部边不能相交),然而脑子却无法转弯,下意识觉得一定要把内边接在两个不同的外点。。。好惨啊就在AC边缘(泪

#include<iostream>  
#include<algorithm>  
#include<string>  
#include<map>//ll dx[4]={0,0,-1,1};ll dy[4]={-1,1,0,0};  
#include<set>//  
#include<vector>  
#include<cmath>  
#include<stack>  
#include<string.h>  
#include<stdlib.h>  
#include<cstdio>   
#define ll long long
#define lowbit(x) (x) & (-x)
using namespace std;
map<char,int> r[27];
int main(){    
	int t;
	cin>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		if(n<=4){
			if(m!=n){
				cout<<"-1 -1"<<endl;
				continue; 
			} 
			for(int i=1;i<=n;++i){
				if(i!=n)
					cout<<i<<" "<<i+1<<endl;
				else
					cout<<n<<" "<<1<<endl;
			}
		}
		else{
			if(2*(n-4)+4<m||m<n){
				cout<<"-1 -1"<<endl;
				continue; 
			} 
			//q+2*p=m  q+p=n 
			int p=m-n,q=n-p;
			for(int i=1;i<=q;++i){
				if(i!=q)
					cout<<i<<" "<<i+1<<endl;
				else
					cout<<q<<" "<<1<<endl;
			}
			for(int i=q+1;i<=n;++i){
				cout<<1<<" "<<i<<endl;
				cout<<3<<" "<<i<<endl;
			}
		}
	}
    return 0;    
}   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值