UVA Live 4732 Jinhan 带权并查集 2009 Asia Seoul Regional

During the Samhan Periodor the Proto-Three Kingdoms Period, whichrefers to the period af- ter the fall of Gojoseon and beforethe matu- ration of Goguryeo, Baekje, and Sillainto full- fledged kingdoms, the city-states of central and southern KoreanPeninsula were groupedinto three confederacies called Mahan,Jinhan, and Byeonhan. Sam means three, and Han is a Ko- rean word meaning great or leader. The names of theseconfederacies are reflected in the cur- rent name of Korea,Daehan Minguk (literally, “Great HanPeople’s Nation”).

One of the city-states calledSaro-guk, which was established by KingPark Hyeokgeose in 57 BCE, around present-dayGyeongju, was the

leader of Jinhan confederacy. As the city-state expanded, it changedits name to Silla, whichwas the longest sustained dynastyin Asian history. We knew little aboutother city-states of Jinhan confederacy, with theexception of theirnames.

Recently, Prof. Choi, who is a highly considered archaeologist, announced that he had found thetomb of King Park Hyeokgeose. By virtue of his major archaeological discovery, we get to know a little of the dailylife of Jinhanpeople. However,even the locations of city-states of Jinhan confederacy except for Saro-guk have beennot known as yet. Thanksto his successof deciphering theinscription engraved on the stone wall of the tomb,the distances between some pairs of city-states of Jinhan confederacy including pairs between Saro-gukand every othercity-state have been known.

An ambitious researchfor estimating the locations of all city-states of Jinhan confederacy is initiated by Prof. Choiand his research group. He conjectures that the city-states of Jinhan confederacy were located in a row. His conjecture is based on the knowledge that Jinhan confederacy was located at between the TaebaekMountains and East Sea. To verifyhis conjecture, he develops a mathematicalmodel, where the area occupied by Jinhanconfederacy is simplified into a straight line, say the x-axis, and the distance betweentwo citystates is represented by a positive integer.The location of a city-state can be described by a point on the x-axis. It is assumedthat Saro-guk is located at the originof the x-axis.

Prof. Choi wants to determine whetheror not it is possibleto locate all the city-states of Jinhan confederacy on the x-axis subjectto the distance constraints betweenthe city-states. Of course, no two city-states should occupy the same location. Write a program that can help him. We denoteby n the number of city-states of Jinhan confederacy, and assume that the city-states are numbered from 1 to n inclusive and thus no two citystates have the same number. Saro-guk has a number of 1. Thedistances between some pairs of city-states including pairs of Saro-gukand every othercity-state are given as input.

For example, if n is equalto three, thedistance between city-states numbered 1 and2 is four, and the distancebetween city-states 1 and 3 is also four, then it is possible to locate the city-states 1, 2,and 3 at positions 0, 4, and -4 on the x-axis,respectively. They can be located at positions 0, -4, and 4, too. However, they cannot be locatedneither at positions0, 4, and 4 nor at positions0, -4, and -4.

 

Input

≤      ≤                          ≤       ≤

 

Your programis to read from standardinput. The inputconsists of T test cases. The number of testcases T is given in the firstline of the input. The first line of each test case contains two integers. The first integer, n, is the number of city-states of Jinhan confederacy, and the secondinteger, m, is thenumber of pairs of citystates whose distance is known, where 1  3, 000 and 1   m   300, 000.   In the following m lines, eachline contains threeintegers u, v, and d which represent thatu and v are known to be at a distanced apart, where1 ≤ d ≤ 300, 000, 000.

Output

Your program is to write to standard output.Print exactly two linesfor each test case. The first line ofeach test case should containthe number n of city-states of Jinhan confederacy. It should followthe second line containing the positions of city-states 1, 2, . . ., and n in order if they can be located on thex-axis satisfying all the mentionedconditions; otherwise, it should containjust ‘impossible’. If there are multiple solutions, pick anyone of them.

 

Sample Input

3

3

2

 

1

2

4

1

3

4

3

3

 

1

2

4

3

2

4

3

1

4

4

6

 

1

2

1

2

3

1

3

4

1

1

3

2

2

4

2

4

1

3

 

Sample Output

3

0  4 -4

3

impossible

 4

0  1  2 3


在一个一维坐标系上有N个城市,现在给出某些城市之间的距离,保证1号城市和所有城市的距离都知道,1号城市始终在原点,问是否存在方案使所有城市的位置都确定。两座城市不能在同一个点。


既然选1号城市为原点,且1号城市到其他城市的距离都知道,就先推出所有城市到1号城市的距离。

利用并查集处理已经得到相互关系的点。

用d[i]表示 i 号节点在1号节点的左边还是右边,左边为0,右边为1,利用带权并查集的性质用异或推出所有城市之间的关系。

第一次知道,并查集还能这么玩!


#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 <stack>
#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=3005,maxk=300005,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);  
int f[maxn],pos[maxn],d[maxn],head[maxn];
int num;
map<int,vector<int> > mp;

struct Edge {
	int from,to,pre;
	ll dist;
};
Edge edge[maxk];

void addedge(int from,int to,ll dist) {
	edge[num]=(Edge){from,to,head[from],dist};
	head[from]=num++;
}

bool cmp(Edge a,Edge b) {
	return a.from<b.from || (a.from==b.from&&a.to<b.to);
}

int find(int x) {
	if (x==f[x]) return x; else {
		int t=f[x];
		f[x]=find(f[x]);
		d[x]=d[x]^d[t];    //保证和父亲方向不同 
		return f[x];
	}
}

bool solve(int n,int m) {
	int i;
	for (i=0;i<m;i++) {
		if (edge[i].from!=1) break;
		int to=edge[i].to;
		pos[to]=edge[i].dist;
		int size=mp[pos[to]].size();
		if (size<2) {
			mp[pos[to]].push_back(to);
			if (size==1) {
				int x=mp[pos[to]][0];
				int fa=find(x),fb=find(to);
				if (fa!=fb) {
					f[fa]=fb;
					d[fa]=d[x]^d[to]^1; 
				} else if (d[x]^d[to]==0) return false;
			}
		} else return false;
	}
	for (;i<m;i++) {
		int from=edge[i].from,to=edge[i].to;
		if (pos[from]+pos[to]==edge[i].dist) {   //在1的不同侧 
			int fa=find(from),fb=find(to);
			if (fa!=fb) {
				f[fa]=fb;
				d[fa]=d[from]^d[to]^1; 
			} else if (d[from]^d[to]==0) return false;
		} else if (abs(pos[from]-pos[to])==edge[i].dist) { //在1的同侧 
			int fa=find(from),fb=find(to);
			if (fa!=fb) {
				f[fa]=fb;
				d[fa]=d[from]^d[to]^0; 
			} else if (d[from]^d[to]==1) return false;
		} else return false;
	}
	for (i=1;i<=n;i++) find(i);
	return true;
}

int main() {
	int cas;
	scanf("%d",&cas);
	while (cas--) {
		int n,m,x,y,i;
		ll di;
		scanf("%d%d",&n,&m);
		printf("%d\n",n);
		num=0;
		mp.clear();
		memset(head,-1,sizeof(head));
		for (i=1;i<=n;i++) f[i]=i;
		for (i=1;i<=m;i++) {
			scanf("%d%d%lld",&x,&y,&di);
			if (x>y) swap(x,y);
			addedge(x,y,di);
		}
		sort(edge,edge+num,cmp);
		mem0(d);mem0(pos);
		pos[0]=0;
		if (solve(n,m)) {
			printf("0");
			for (i=2;i<=n;i++) {
				if (d[i]==1) printf(" %d",pos[i]); 
				    else printf(" -%d",pos[i]); 
			}
			printf("\n");
		} else printf("impossible\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值