Problem D. Championships
Input fle: standard input
Output fle: standard output
Time limit: 1.5 seconds
Memory limit: 256 mebibytes
The Computer Sports World Championships is the most important event in the calendar of every electronic entertainment fan. This year, the championships will be held in the kingdom of Byteotia. The
organizing committee, appointed by the king Byteasar, is facing a difcult task – it has to decide in which
Byteotian cities competitions will take place. There are n cities in Byteotia (numbered 1 through n) connected by m two-way roads.
The committee hopes that the championship will attract crowds of fans from all over the world. Obviously,
the fans will travel frequently between the cities to watch the competitions of various e-sport types. The
priority is therefore that the set of cities, hosting the championships events, is well connected.
We call a set of citiesWe call a set of cities S well connected, if:
(1) From every city of the set(1) From every city of the set S there are at least d direct connections to other cities of S.
(2) Between any two cities of(2) Between any two cities of S there exists a route running only through the cities belonging to the
setset S.
Additionally, to minimize the average number of visitors in each city, the committee would prefer the
chosen set to be possibly large.Additionally, to minimize the average number of visitors in each city, the committee would prefer the
chosen set to be possibly large.
Input
The frst line of the input contains three integers n, m and d (2 ≤ n ≤ 200000, 1 ≤ m ≤ 200000,
11 ≤ d < n) denoting the the number of cities, the number of roads in Byteotia and the parameter d,
respectively. Nextrespectively. Next m lines describe the Byteotian roads. The i-th of these lines contains two integers
ai and bi (1 ≤ ai; bi ≤ n, ai 6= bi) indicating that the i-th road connects the cities numbered ai and bi.
Each pair of cities is connected by at most one direct road.Each pair of cities is connected by at most one direct road.
Output
If it is not possible to choose a set of cities of Byteotia that is well connected, the only line of the output
should contain the word “NIE” (Polish for no).
Otherwise, the output should contain the most numerous set of cities that is well connected, in the
following format. The frst line should contain the numberOtherwise, the output should contain the most numerous set of cities that is well connected, in the
following format. The frst line should contain the number k denoting the size of the found set. The
second line should containsecond line should contain k numbers representing the cities belonging to the set, in ascending order.
In case there are multiple solutions, your program can output any of them.In case there are multiple solutions, your program can output any of them.
Examples
standard input | standard output |
4 4 2 1 2 2 3 3 4 4 2 | 3 2 3 4 |
3 2 2 1 2 2 3 | NIE |
图论题。
给你一个无向图,让你找到一个子图,使得这个子图中所有点的度数都不小于d。不保证图是连通的。要求这个子图中点数最多,并输出这些点的编号。
贪心。把度数小于d的点删掉,删的过程中又会增加度数小于d的点,再删,直到不存在这样的点。
全删完之后,剩下的每一个连通的图都符合题目要求。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <bitset>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=200005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int du[maxn],head[maxn],size[maxn],col[maxn];
bool visit[maxn],mark[maxn];
int num,cnum;
struct Edge {
int from,to,pre;
};
Edge edge[maxn*2];
void addedge(int from,int to) {
edge[num]=(Edge){from,to,head[from]};
head[from]=num++;
edge[num]=(Edge){to,from,head[to]};
head[to]=num++;
}
void dfs(int now) {
visit[now]=1;
size[cnum]++;
col[now]=cnum;
for (int i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (!visit[to]) dfs(to);
}
}
int main() {
int n,m,d,i,j,x,y;
scanf("%d%d%d",&n,&m,&d);
memset(head,-1,sizeof(head));
mem0(du);
num=cnum=0;
for (i=1;i<=m;i++) {
scanf("%d%d",&x,&y);
addedge(x,y);
du[x]++;du[y]++;
}
mem0(visit);mem0(mark);
queue<int> q;
for (i=1;i<=n;i++) {
if (du[i]<d) q.push(i),mark[i]=visit[i]=1;
}
while (!q.empty()) {
int now=q.front();
q.pop();
for (i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
du[to]--;
if (du[to]<d&&!visit[to]) q.push(to),mark[to]=visit[to]=1;
}
}
for (i=1;i<=n;i++) {
if (!visit[i]) {
cnum++;size[cnum]=0;
dfs(i);
}
}
if (cnum==0) {
printf("NIE\n");
return 0;
}
int ans=1,tot=size[1];
for (i=2;i<=cnum;i++) {
if (size[i]>tot) tot=size[i],ans=i;
}
printf("%d\n",tot);
for (i=1;i<=n;i++) {
if (!mark[i]&&col[i]==ans) printf("%d ",i);
}
return 0;
}