HDU 4039 社交网络 暴力+优先队列

73 篇文章 21 订阅
56 篇文章 0 订阅

 

因为N数据实在是1000*1000。相当的小。 最多开到2000*2000。 这样的话,直接暴力就可以解决了。

 

然后我们用trie树建立映射关系,之后开始建图搜索匹配。  n*n的搜索完全可以接受。

 

题目意思就是模拟推荐好友的功能。

 

 

/*
 * @author ipqhjjybj
 * @time 20130907
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#define foreach(it,x) for(vector<int>::iterator it=x.begin();it!=x.end();it++)
using namespace std;

const int N=2111;
struct cmp{
    char *s;
    bool operator < (const cmp & tmp) const{
        return strcmp(s,tmp.s)>0;
    };
    cmp(){};
    cmp(char *_s){
        s=_s;
    }
};
struct node{
    node *go[26];
    int id;
    int end;
    void clear(){
        memset(go,0,sizeof(go));
        id=-1;
        end=0;
    }
}AlphaTree[4000000],*root,*cnt;
int cid;
char str[N][40];
int g[N][N];
int n,q;
vector<int> vi[N];
void Init(){
    root=cnt=AlphaTree;
    root->clear();
    cnt++;
    cid=0;
    memset(g,0,sizeof(g));
}
int Insert(char *s){
    node *cur=root;
    char *p=s;
    int x;
    for( ;*s;s++){
        x=*s-'a';
        if(!cur->go[x]){
            cur->go[x]=cnt;
            cnt->clear();
            cnt++;
        }
        cur=cur->go[x];
    }
    if(cur->id==-1){
        cur->id=cid;
        strcpy(str[cid],p);
        vi[cid].clear();
        cid++;
    }
    return cur->id;
}
int ct[N];
void solve(int id){
    for(int i=0;i<cid;i++)
        ct[i]=0;
    foreach(u,vi[id])
        foreach(v,vi[*u]){
            if(!g[id][*v]&&*v!=id){
                ct[*v]++;
            }
        }
    int max_value=0;
    for(int i=0;i<cid;i++){
        max_value=max(max_value,ct[i]);
    }
    if(!max_value){
        printf("-\n");
    }else{
        priority_queue<cmp> Q;
        for(int i=0;i<cid;i++)
            if(max_value==ct[i])
                Q.push(cmp(str[i]));

        printf("%s",Q.top().s);
        Q.pop();
        while(!Q.empty()){
            printf(" %s",Q.top().s);
            Q.pop();
        }
        printf("\n");
    }
}
int main(){
    int t,tt=0,id1,id2;
    char str1[20],str2[20];
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&q);
        Init();
        for(int i=0;i<n;i++){
            scanf("%s %s",str1,str2);
            id1=Insert(str1);
            id2=Insert(str2);
            if(!g[id1][id2]){
                vi[id1].push_back(id2);
                vi[id2].push_back(id1);
            }
            g[id1][id2]=g[id2][id1]=1;
        }

        printf("Case %d:\n",++tt);
        while(q--){
            scanf("%s",str1);
            solve(Insert(str1));
        }
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值