HDU 3234Exclusive-OR Regional的題就是硬啊臥槽

來源:互聯網
上載者:User

標籤:style   os   io   for   cti   ar   代碼   amp   

帶權並查集,思路很清晰,代碼很難看。

對於 I u v ,分以下幾種情況不合法。

1.num[u] 已確定 && num[u]  != v 。

2.num[u] 的根已確定,若num[u] == v與根節點有衝突。

若合法,則修改num[u] 且 修改num[u]的根節點的資訊。


對於 I u v w   ,分以下幾種情況不合法。

1.num[u] ,num[v] 均已確定或均可通過根節點確定 且 num[u]^num[v] != w;

2.若u,v在一個集合內,且num[u] ^ num[root]  ^ num[v] ^num[root] = num[u]^num[v] != w;

若合法,且u,v不在一個集合內,合并u,v所在的集合,若num[root_u]已知,num[root_v]未知(設root_v合并後新集合的根),則更新num[root_v]。

對於詢問:

首先將確定的數的抑或結果計算出來,然後對於剩下的必須符合可以分成X份,每份中必須有偶數個元素。

因為任意兩個同根的元素可以由num[u] ^ num[root]  ^ num[v] ^num[root] = num[u]^num[v] 得出。

否則輸出I don‘t know.


有些題解的解法簡直炫酷到沒朋友,通過虛擬出一個值為零的節點節省了很多代碼,可見預先設計出好的思路是有多重要。

#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <stack>#include <string>#include <map>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long#define ULL unsigned long long#define _LL __int64#define INF 0x3f3f3f3f#define Mod 300using namespace std;struct N{    int fa,re;}st[20010];int num[20010];int Find(int x,int &R){    int f = x,re = 0,tre = 0,temp,tf;    while(f != st[f].fa)    {        re ^= st[f].re;        f = st[f].fa;    }    R = re;    while(x != st[x].fa)    {        temp = st[x].re;        tf = st[x].fa;        st[x].re = re^tre;        st[x].fa = f;        tre ^= temp;        x = tf;    }    return x;}bool Merge(int u,int v,int w){    int fu,fv,ru,rv;    fu = Find(u,ru);    fv = Find(v,rv);    if(num[fu] != -1)        num[u] = num[fu]^ru;    if(num[fv] != -1)        num[v] = num[fv]^rv;    if(num[u] != -1 && num[v] != -1)        return (num[u]^num[v]) == w;    if(fu == fv)    {        return (w^ru) == rv;    }    else    {        st[fu].fa = fv;        st[fu].re = w^rv^ru;        if(num[fv] == -1 && num[fu] != -1)        {            num[fv] =  num[fu]^st[fu].re;        }    }    return true;}bool mark[20];int  qu[20];void JudgeQ(char *s){    int i,j,k = 0;    for(i = 0;s[i]  < '0' || s[i] > '9'; ++i)        ;    for(;!(s[i]  < '0' || s[i] > '9'); ++i)        ;    for(;s[i] == ' '; ++i)        ;    int anw = 0,temp,x;    while(s[i] != '\0')    {        temp = 0;        for(;!(s[i]  < '0' || s[i] > '9'); ++i)        {            temp += (s[i]-'0');            temp *= 10;        }        temp = temp/10 + 1;        for(;s[i] == ' '; ++i)            ;        qu[k++] = temp;    }    for(i = 0;i < k; ++i)    {        if(num[qu[i]] != -1)        {            anw ^= num[qu[i]];            continue;        }        if(num[Find(qu[i],x)] != -1)        {            num[qu[i]] = num[Find(qu[i],x)]^x;            anw ^= num[qu[i]];        }    }    memset(mark,false,sizeof(mark));    int ru,rv;    for(i = 0;i < k; ++i)    {        if(mark[i] == false && num[qu[i]] == -1)        {            for(j = i+1;j < k; ++j)            {                if(mark[j] == false && num[qu[i]] == -1 && Find(qu[i],ru) == Find(qu[j],rv))                {                    mark[i] = true,mark[j] = true,anw ^= (ru^rv);                    break;                }            }            if(mark[i] == false)            {                printf("I don't know.\n");                return;            }        }    }    printf("%d\n",anw);}int Judge(char *s){    int i;    for(i = 0;s[i]  < '0' || s[i] > '9'; ++i)        ;    for(;s[i] == ' '; ++i)        ;    int ans = 0;    while(s[i] != '\0')    {        ans++;        for(;!(s[i]  < '0' || s[i] > '9'); ++i)            ;        for(;s[i] == ' '; ++i)            ;    }    return ans;}int main(){    int i,n,m,icase = 1;    char s[100],ord[100];    int u,v,w;    int ans;    bool wrong,first;    while(scanf("%d %d%*c",&n,&m) && (n||m))    {        for(i = 1;i <= n; ++i)            st[i].fa = i,st[i].re = 0,num[i] = -1;        wrong = false,first = true;        ans = 0;        printf("Case %d:\n",icase++);        while(m--)        {            gets(s);            if(first == false)                continue;            if(s[0] == 'I')            {                ans++;                if(Judge(s) == 3)                {                    sscanf(s,"%s %d %d %d",ord,&u,&v,&w);                    u++,v++;                    if(Merge(u,v,w) == false)                        wrong = true;                }                else                {                    sscanf(s,"%s %d %d",ord,&u,&w);                    u++;                    if(num[u] == -1 && num[Find(u,v)] == -1)                    {                        num[u] = w;                        num[Find(u,v)] = w^st[u].re;                    }                    else if(num[u] == -1)                    {                        if((num[Find(u,v)]^st[u].re) != w)                            wrong = true;                        else                            num[u] = w;                    }                    else if(num[u] != w)                        wrong = true;                }                if(wrong && first)                {                    printf("The first %d facts are conflicting.\n",ans);                    first = false;                }            }            else            {                JudgeQ(s);            }        }        printf("\n");    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.