题意:每次给出每两个数之间的大小差值。在给出关系的过程中插入询问:数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; }