bzoj2140: 稳定婚姻

这题毒瘤选手选择hash之后再强联通。

然后stm这个hash两个长度不一样的字符串哈希值还会一样!?虽然我的确只是乘了strlen次方,但是这个Rp也是。。。。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const LL mod=1000000007;
map<LL,LL>mp;
char ss[20];
LL Hash()
{
    LL ret=0;
    for(int i=1;i<=15;i++)
    {
        if('a'<=ss[i]&&ss[i]<='z')ret+=ss[i]-'a'+1;
        if('A'<=ss[i]&&ss[i]<='Z')ret+=ss[i]-'A'+1+26;
        ret=(ret*60)%1000000007;
    }
    return ret;
}

struct node
{
    int x,y,next;
}a[410000];int len,last[11000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int z,dfn[11000],low[11000];
int top,sta[11000];bool v[11000];
int cnt,belong[11000];
void strong_unicom(int x)
{
    dfn[x]=low[x]=++z;
    sta[++top]=x;v[x]=true;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(dfn[y]==0)
        {
            strong_unicom(y);
            low[x]=min(low[x],low[y]);
        }
        else
        {
            if(v[y]==true)
                low[x]=min(low[x],dfn[y]);
        }
    }
    if(dfn[x]==low[x])
    {
        int i;cnt++;
        do
        {
            i=sta[top];top--;
            v[i]=false;
            belong[i]=cnt;
        }while(i!=x);
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++)
    {
        LL wf,hb;
        memset(ss,0,sizeof(ss));scanf("%s",ss+1);wf=Hash();
        memset(ss,0,sizeof(ss));scanf("%s",ss+1);hb=Hash();
        mp[wf]=i,mp[hb]=i+n;
        ins(i,i+n);
    }
    
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        LL gf,bf;
        memset(ss,0,sizeof(ss));scanf("%s",ss+1);gf=Hash();
        memset(ss,0,sizeof(ss));scanf("%s",ss+1);bf=Hash();
        ins(mp[bf],mp[gf]);
    }
    
    z=cnt=top;
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(v,false,sizeof(v));
    for(int i=1;i<=2*n;i++)
        if(dfn[i]==0)strong_unicom(i);
    
    for(int i=1;i<=n;i++)
        if(belong[i]==belong[i+n])printf("Unsafe\n");
        else printf("Safe\n");
    return 0;
}

 

posted @ 2018-03-23 09:51  AKCqhzdy  阅读(150)  评论(0编辑  收藏  举报