国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

cf 766 d Mahmoud and a Dictionary(帶權并查集)

2019-11-10 22:04:40
字體:
來源:轉載
供稿:網友

題意:

給一些單詞,它們可能是同義或者反義,給出一些關系定義,從前面的定義開始建立關系,如果有的關系定義和之前的沖突輸出NO,否則輸出YES。然后查詢q次單詞x和單詞y的關系。

解題思路:

很明顯就是帶權并查集,但是我不太會用,去網上找了食物鏈的代碼,改了下代碼,但是每改公式,強行把關系差為2和3的都當做反義關系,結果錯了。結束后去學習了下帶權并查集,然后直接把公式改了改就過了,發現其實當時xjb改也能過。

用一個數組rank[x]表示x和他的祖先直接的關系,0表示他們是同義,1表示他們是反義。

點于點之間的關系可以用向量來理解,為什么是向量我也不知道。比如說題目定義x與y的關系為x->y,那么x->fa[y]=x->y+y->fa[y]。也就是rank[x]=x與y的關系+rank[y];

#include <bits/stdc++.h>using namespace std;const int maxn=1e5+5;struct p{    char x[22];}a[maxn+5];int fat[maxn],ran[maxn], n;bool cmp(p a, p b){    if(strcmp(a.x,b.x)<0)return true;    else return false;}int fin(char key[]){    int l=1, r=n, mid=(1+n)/2;    while(l<=r)    {        mid=(l+r)/2;        if(strcmp(key, a[mid].x)>0)        {            l=mid+1;        }        else if(strcmp(key, a[mid].x)<0)        {            r=mid-1;        }        else return mid;//        PRintf("%d %s/n", mid, a[mid].x);    }    return 0;}void Init(int n)//初始化重要{    for(int i=1; i<=n; i++)    {        fat[i]=i;//初始化都是指向(看做)自己        ran[i]=0;//0同義 1反義    }    return;}int Find(int x)//找尋父節點+路徑壓縮{    if(x==fat[x])        return fat[x];    int y=Find(fat[x]);    ran[x]=(ran[x]+ran[fat[x]])%2;//遞歸后從祖先節點向后到每個孩子來計算    return fat[x]=y;//路徑壓縮}int main(){    int  m, q;    scanf("%d%d%d", &n, &m, &q);    int i;    for(i=1; i<=n; i++)scanf("%s", a[i].x);    sort(a+1, a+n+1, cmp);    Init(n);    int e, xx, yy;    char x[22], y[22];    for(i=0; i<m; i++)    {        scanf("%d%s%s", &e, x, y);        xx=fin(x);        yy=fin(y);        int x1=Find(xx);        int y1=Find(yy);//        printf("%d %d/n", x1, y1);        int ans=0;        if(x1==y1)//共父節點才能判斷出關系        {            if((ran[xx]-ran[yy]+2)%2==e-1)                printf("YES/n");            else printf("NO/n");        }        else printf("YES/n"), ans=1;        if(ans)        {        fat[x1]=y1;//連接兩父節點        ran[x1]=(-ran[xx]+e-1+ran[yy]+2)%2;        /*這里只對祖先x1賦值,可能有童鞋就疑問為什么xx沒有賦值,其實xx在路徑壓縮里會根據          它和祖先的關系賦值,所以這里不用對xx賦值*/        }    }    for(i=0; i<q; i++)    {        scanf("%s%s", x, y);        xx=fin(x);        yy=fin(y);        int x1=Find(xx);        int y1=Find(yy);        if(x1==y1)//共父節點才能判斷出關系        {            int ans=(ran[xx]-ran[yy]+2)%2+1;            printf("%d/n", ans);        }        else printf("3/n");    }    return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 辽宁省| 疏附县| 财经| 安义县| 公安县| 天长市| 广德县| 台湾省| 溧阳市| 东乡族自治县| 东乌珠穆沁旗| 孟州市| 乌拉特后旗| 鸡东县| 长汀县| 磴口县| 靖宇县| 东乌珠穆沁旗| 沈阳市| 龙川县| 宝坻区| 济源市| 讷河市| 富民县| 伊金霍洛旗| 华蓥市| 东山县| 祁阳县| 丰都县| 镇远县| 昌宁县| 枣庄市| 南安市| 宁化县| 彰化县| 延吉市| 桃源县| 乐山市| 中山市| 中江县| 柳州市|