樹形結構+拓撲思維 Codeforces Round #285 (Div. 2) C題 Misha and Forest

Misha and Forest

Let’s define a forest as a non-directed acyclic graph (also without loops and parallel edges). One day Misha played with the forest consisting of n vertices. For each vertex v from 0 to n - 1 he wrote down two integers, degreev and sv, were the first integer is the number of vertices adjacent to vertex v, and the second integer is the XOR sum of the numbers of vertices adjacent to v (if there were no adjacent vertices, he wrote down 0).

Next day Misha couldn’t remember what graph he initially had. Misha has values degreev and sv left, though. Help him find the number of edges and the edges of the initial graph. It is guaranteed that there exists a forest that corresponds to the numbers written by Misha.


題目大意:n 個點,每個點都有兩個表示關係,degreev 和 sv, 分別代表這個點的度數和與這個點相連的點異或值和;讓你構造一張無向無環圖(就是樹)滿足這些條件;

構造題終歸是比較難的;

可以發現,葉子結點只有一個度,並且與它連接的點的異或值和值 sv 一定是它的父節點;

發現這個,這題就可以套用拓撲排序的思路了,每次找出 degreev 等於1的點,入隊,然後擴展;

代碼:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100100;
const int M=2000100;
const LL mod=1e9+7;
int s[N],d[N];
queue<int>qu;
vector<pa>ans;
void bfs(){
	while(!qu.empty()){
		int p=qu.front();
		qu.pop();
		if(d[p]==1){//這個特別注意 
			ans.push_back(pa(p,s[p]));
			d[s[p]]--,s[s[p]]^=p;
			if(d[s[p]]==1) qu.push(s[p]);
		}
	}
}
int main(){
	int n;scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d%d",&d[i],&s[i]);
	for(int i=0;i<n;i++){
		if(d[i]==1) qu.push(i);
	}
	bfs();
	printf("%d\n",(int)ans.size());
	for(int i=0;i<(int)ans.size();i++) printf("%d %d\n",ans[i].first,ans[i].second);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章