Google Spaceship Defence 面试题目 并查集+最短路

来源:互联网 发布:92game仿影视大全源码 编辑:程序博客网 时间:2024/06/05 20:41

点击打开链接

题意:给了n个地点,然后每个地点的名称,若名称相同则可以认为这两个地点距离为0,下面m个关系代表两个地点的距离,有向的边,q个询问,两个点的距离,想做的密码是nefu

思路:简单的最短路题目,因为有相同的点,可以用并查集将这些点放到一个集合中,然后建图建的就是父节点就行了,找相同关系我用的Trie树,但是map应该也可以直接做,没用过map只能写Trie树了,剩下的就是最短路模版,easy~~~

#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=400010;int f[maxn],num[maxn];struct edge{    int to,cost;    edge(){}    edge(int a,int b){to=a;cost=b;}};typedef pair<int,int>P;vector<edge>G[maxn];int dis[maxn];void dijkstra(int st){    priority_queue<P,vector<P>,greater<P> >que;    fill(dis,dis+maxn,inf);    dis[st]=0;    que.push(P(0,st));    while(!que.empty()){        P p=que.top();que.pop();        int v=p.second;        if(dis[v]<p.first) continue;        for(unsigned int i=0;i<G[v].size();i++){            edge e=G[v][i];            if(dis[e.to]>dis[v]+e.cost){                dis[e.to]=dis[v]+e.cost;                que.push(P(dis[e.to],e.to));            }        }    }}int find1(int x){    if(x==f[x]) return f[x];    int t=f[x];    f[x]=find1(f[x]);    return f[x];}void unite(int a,int b){    int aa=find1(a);    int bb=find1(b);    if(aa==bb) return ;    f[aa]=bb;    num[bb]+=num[aa];}struct Trie{    Trie *next[96];    int v;};Trie *root;char str1[30],str2[30];void creatTrie(char *str,int idx){    int len=strlen(str);    Trie *p=root,*q;    for(int i=0;i<len;i++){        int id=str[i]-'0';        if(p->next[id]==NULL){            q=(Trie *)malloc(sizeof(Trie));            q->v=0;            for(int j=0;j<96;j++)                q->next[j]=NULL;            p->next[id]=q;        }        p=p->next[id];    }    p->v=idx;}int findtrie(char *str){    int len=strlen(str);    Trie *p=root;    for(int i=0;i<len;i++){        int id=str[i]-'0';        p=p->next[id];        if(p==NULL) return 0;    }    return p->v;}int dealtrie(Trie *T){    if(T==NULL) return 0;    for(int i=0;i<96;i++) if(T->next[i]!=NULL) dealtrie(T->next[i]);    free(T);    return 0;}int main(){    int T,n,cas=1,m,u,v,cost,q;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        for(int i=0;i<maxn;i++) G[i].clear();        for(int i=0;i<=2*n;i++){            f[i]=i;num[i]=1;        }        int k=1;        root=(Trie *)malloc(sizeof(Trie));        for(int i=0;i<96;i++) root->next[i]=NULL;        for(int i=1;i<=n;i++){            scanf("%s",str1);            int ans1=findtrie(str1);            if(ans1==0) creatTrie(str1,i);            else unite(ans1,i);        }        scanf("%d",&m);        for(int i=0;i<m;i++){            scanf("%d%d%d",&u,&v,&cost);            int tmp;            int aa=find1(u),bb=find1(v);            if(aa==bb) tmp=0;            else tmp=cost;            G[aa].push_back(edge(bb,tmp));        }        scanf("%d",&q);        printf("Case #%d:\n",cas++);        while(q--){            scanf("%d%d",&u,&v);            int aa=find1(u),bb=find1(v);            if(aa==bb) printf("0\n");            else{                dijkstra(aa);                if(dis[bb]==inf) printf("-1\n");                else printf("%d\n",dis[bb]);            }        }        dealtrie(root);    }    return 0;}

0 0