【枚舉】【並查集】Gym - 101243F - Vitamins
阿新 • • 發佈:2017-10-04
can inpu 大於 name clu pre () else if 指向
題意:有n片藥,有三種顏色,白色比紅色重,紅色比藍色重,給你一些它們之間的重量關系,比如1>3,2=4之類,問你它們的顏色,如果沒法判斷的輸出?。
先並查集把等於號全縮起來,然後按照大於號建圖,就是一張DAG,枚舉所有的點,發現它如果是一個長度為3的鏈的中間結點,那麽它、它指向的、指向它的顏色都可以判斷了。
其他的都無法判斷。
#include<cstdio> #include<cstring> using namespace std; int v[2][499505],nex[2][499505],first[2][1005],e[2]; void AddEdge(int U,int V,bool Type){ v[Type][++e[Type]]=V; nex[Type][e[Type]]=first[Type][U]; first[Type][U]=e[Type]; } int fa[1005],xs[499505],ys[499505]; char cs[499505]; int n,m; char s[105]; int find(int x){ return x==fa[x] ? x : fa[x]=find(fa[x]); } int trans(int l,int r){ int res=0; for(int i=l;i<=r;++i){ res=res*10+s[i]-‘0‘; } return res; } char anss[1005]; int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ fa[i]=i; } for(int i=1;i<=m;++i){ scanf("%s",s); int len=strlen(s); for(int j=0;j<len;++j){ if(!(s[j]>=‘0‘ && s[j]<=‘9‘)){ xs[i]=trans(0,j-1); ys[i]=trans(j+1,len-1); cs[i]=s[j]; if(s[j]==‘=‘){ int f1=find(xs[i]),f2=find(ys[i]); if(f1!=f2){ fa[f1]=f2; } } break; } } } for(int i=1;i<=m;++i){ if(cs[i]==‘>‘){ AddEdge(find(xs[i]),find(ys[i]),0); AddEdge(find(ys[i]),find(xs[i]),1); } else if(cs[i]==‘<‘){ AddEdge(find(ys[i]),find(xs[i]),0); AddEdge(find(xs[i]),find(ys[i]),1); } } for(int i=1;i<=n;++i){ int f=find(i); if(f!=i){ continue; } if(first[0][f] && first[1][f]){ anss[i]=‘R‘; for(int j=first[0][f];j;j=nex[0][j]){ anss[v[0][j]]=‘B‘; } for(int j=first[1][f];j;j=nex[1][j]){ anss[v[1][j]]=‘W‘; } } } for(int i=1;i<=n;++i){ int f=find(i); if(f!=i){ anss[i]=anss[f]; } } for(int i=1;i<=n;++i){ if(anss[i]!=0){ putchar(anss[i]); } else{ putchar(‘?‘); } } puts(""); return 0; }
【枚舉】【並查集】Gym - 101243F - Vitamins