UVALive 6187 Never Wait for Weights 带权并查集
题意:每次给出每两个数之间的大小差值。在给出关系的过程中插入询问:数a和数b的差值,若不能确定,输出UNKNOWN
解法:相对大小关系的处理:并查集
1.给出两点的相对大小关系后,找到两个点的根节点,并利用路径压缩,将两个点父亲指向根节点。然后将根节点进行合并,并给出根节点之间的相对大小关系
2.询问时,同时找到该点到根节点的距离,相减即可得到相对大小。
//meek #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <sstream> #include <vector> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define pb push_back #define fi first #define se second #define MP make_pair inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } //**************************************** const int N=500000+100; const ll inf = 1ll<<61; const int mod= 1000000007; char ch[20]; int d[N],parent[N],flag,n; ll ans; void init () { for(int i=0;i<=n;i++) parent[i]=i; mem(d); } int finds(int x){ if(x==parent[x])return x; int fy=finds(parent[x]); d[x] = d[parent[x]] + d[x]; return parent[x]=finds(parent[x]); } int main() { int a,b,m,w; while(scanf("%d%d",&n,&m)!=EOF) { if( n==0 &&m==0) break; init(); for(int i=1;i<=m;i++) { scanf("%s",ch); if(ch[0]=='!') { scanf("%d%d%d",&a,&b,&w); int fx=finds(a); int fy=finds(b); if(fx!=fy) parent[fy]=fx,d[fy]=d[a]-w-d[b]; } else { scanf("%d%d",&a,&b); int fx=finds(a); int fy=finds(b); if(fx==fy) { cout<<d[a]-d[b]<<endl; } else { printf("UNKNOWN\n"); } } } } return 0; }