QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#360087#5160. Kebab Pizzakevinyang#WA 13ms48392kbC++174.0kb2024-03-21 11:27:562024-03-21 11:27:57

Judging History

你现在查看的是最新测评结果

  • [2024-03-21 11:27:57]
  • 评测
  • 测评结果:WA
  • 用时:13ms
  • 内存:48392kb
  • [2024-03-21 11:27:56]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define int long long
struct DisjointSet{
	vector<int>parent,sz,mn,mx;
	int size;
	void init(int n){
		size = n;
		parent.resize(n+1); sz.resize(n+1); mx.resize(n+1); mn.resize(n+1);
		for(int i = 1; i<=n; i++){
			parent[i] = i;
			sz[i] = 1;
			mx[i] = i;
			mn[i] = i;
		}
	}
	int find(int x){
		if(parent[x]==x)return x;
		return find(parent[x]);
	}
	void Union(int x, int y){
		x = find(x); y = find(y);
		if(x==y)return;
		if(sz[x]<sz[y]){
			parent[x] = y;
			mx[y] = max(mx[y],mx[x]);
			mn[y] = min(mn[y],mn[x]);
			sz[y]+=sz[x];
		}
		else{
			parent[y] = x;
			sz[x]+=sz[y];
			mx[x] = max(mx[x],mx[y]);
			mn[x] = min(mn[x],mn[y]);
		}
	}
};
/*
condition:
when multi edges are removed and self edges are removed 

if there is a cycle, there can only be one and all nodes are adjacent to the cycle

if there is a forest, then everything touches the diameter of the tree
*/
int mxn = 200005;
vector<vector<int>>adj(mxn); int ln = 20;
vector<vector<int>>dp(mxn,vector<int>(ln));
vector<int>lvl(mxn);
void dfs(int u, int p){
	lvl[u] = lvl[p]+1;
	dp[u][0] = p;
	for(int i = 1; i<ln; i++){
		dp[u][i] = dp[dp[u][i-1]][i-1];
	}
	for(int nxt: adj[u]){
		if(nxt==p)continue;
		dfs(nxt,u);
	}
}
int lca(int x, int y){
	if(lvl[x]<lvl[y])swap(x,y);
	int dif = lvl[x]-lvl[y];
	for(int i = 0; i<ln; i++){
		if((1<<i)&dif){
			x = dp[x][i];
		}
	}
	if(x==y)return x;
	for(int i = ln-1; i>=0; i--){
		if(dp[x][i]!=dp[y][i]){
			x = dp[x][i]; y = dp[y][i];
		}
	}
	return dp[x][0];
}
int dist(int x, int y){
	int u = lca(x,y);
	return lvl[x]+lvl[y]-2*lvl[u];
}
signed main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	int n,k;
	cin >> n >> k;
	DisjointSet ds;
	ds.init(k+1);
	int cnt = 0;
	map<pair<int,int>,int>hm;
	pair<int,int>p = {0,0};
	set<int>s;
	for(int i = 1; i<=n; i++){
		int x,y;
		cin >> x >> y;
		if(x>y)swap(x,y);
		s.insert(x);
		s.insert(y);
		if(x==y || hm[{x,y}])continue;
		hm[{x,y}] = 1;
		if(ds.find(x)==ds.find(y)){
			cnt++;
			p = {x,y};
		}
		else{
			ds.Union(x,y);
			adj[x].push_back(y);
			adj[y].push_back(x);
		}
	}
	assert((int)s.size() == k);
	if(cnt > 1){
		cout << "impossible\n";
		return 0;
	}
	if(cnt == 1){
		vector<int>cycle(k+1);
		dfs(1,0);
		int x = p.first;
		int y = p.second;
		int u = lca(x,y);
		cycle[u] = 1;
		while(x!=u){
			cycle[x] = 1;
			x = dp[x][0];
		}
		while(y!=u){
			cycle[y] = 1;
			y = dp[y][0];
		}
		for(int i = 1; i<=k; i++){
			bool good = false;
			if(cycle[i])continue;
			for(int nxt: adj[i]){
				if(cycle[nxt])good = true;
			}
			if(!good){
				cout << "impossible\n";
				return 0;
			}
		}
		cout << "possible\n";
		return 0;
	}
	vector<int>dis(k+1);
	vector<bool>vis(k+1);
	vector<int>pre(k+1);
	vector<int>cycle(k+1);
	vector<int>dis2(k+1);
	vector<bool>vis2(k+1);
	vector<int>pre2(k+1);
	for(int i = 1; i<=k; i++){
		if(vis[i])continue;
		queue<int>q;
		q.push(i);
		vis[i] = true;
		int mx = 0; int start = i;
		while(q.size()){
			int cur = q.front(); q.pop();
			for(int nxt: adj[cur]){
				if(vis[nxt])continue;
				vis[nxt] = true;
				dis[nxt] = dis[cur]+1;
				q.push(nxt);
				if(dis[nxt]>mx){
					start = nxt;
					mx = dis[nxt];
				}
			}
		}
		vis2[start] = true;
		mx = 0;
		q.push(start);
		while(q.size()){
			int cur = q.front(); q.pop();
			for(int nxt: adj[cur]){
				if(vis2[nxt])continue;
				vis2[nxt] = true;
				dis2[nxt] = dis2[cur]+1;
				q.push(nxt);
				pre[nxt] = cur;
				if(dis2[nxt] > mx){
					start = nxt;
					mx = dis2[nxt];
				}
			}
		}
		cycle[start] = 1;
		while(pre[start]){
			//cout << start << ' ';
			start = pre[start];
			cycle[start] = 1;
		}
		//cout << '\n';
	}
	for(int i = 1; i<=k; i++){
		if(cycle[i])continue;
		bool good = false;
		for(int nxt: adj[i]){
			if(cycle[nxt])good = true;
		}
		if(!good){
			cout << "impossible\n";
			return 0;
		}
	}
	cout << "possible\n";
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 11ms
memory: 48384kb

input:

7 6
2 2
3 6
1 1
1 5
4 5
6 6
6 5

output:

possible

result:

ok single line: 'possible'

Test #2:

score: 0
Accepted
time: 7ms
memory: 48368kb

input:

5 5
1 3
1 5
2 3
2 5
3 4

output:

possible

result:

ok single line: 'possible'

Test #3:

score: 0
Accepted
time: 7ms
memory: 48356kb

input:

6 7
1 2
2 3
3 4
4 5
3 6
6 7

output:

impossible

result:

ok single line: 'impossible'

Test #4:

score: 0
Accepted
time: 7ms
memory: 48368kb

input:

8 4
1 1
1 2
2 1
2 2
3 3
3 4
4 3
4 4

output:

possible

result:

ok single line: 'possible'

Test #5:

score: 0
Accepted
time: 13ms
memory: 48392kb

input:

4 4
1 2
2 1
3 4
4 3

output:

possible

result:

ok single line: 'possible'

Test #6:

score: 0
Accepted
time: 11ms
memory: 48236kb

input:

5 4
1 1
1 4
2 2
2 4
3 4

output:

possible

result:

ok single line: 'possible'

Test #7:

score: -100
Wrong Answer
time: 7ms
memory: 48236kb

input:

6 4
1 1
1 4
2 2
2 4
3 3
3 4

output:

possible

result:

wrong answer 1st lines differ - expected: 'impossible', found: 'possible'