Problem C. gCampus Google APAC 2016 University Test Round A

来源:互联网 发布:淘宝网皮羽绒服女款 编辑:程序博客网 时间:2024/06/10 14:10

这一题看起来很水,结果被坑了大半天。><

解法就是把所有的点当做起点,求一次最短路。再看这些最短路上有哪些边,这些边就是就是efficient的。

最开始我用一个pre对最短路上的每个点记录其parent node,然后循环从终点推到起点就可以得出这一条最短路上有哪些边。这么做有一个问题,如果st to ed存在多条最短路,pre数组就会被覆盖掉,然后只会记录一条最短路上的边。感觉如果对每一个node内一个pre vector,然后dfs找出所有的最短路也行吧。正解是如果dis[i]+cost[i][j]=dis[j]那么边(i,j)就是在i to j的最短路上。其中dis[i]是st to i的最短路距离,cost是两个点之间的weight。

另外,这一题中两个office之间可能有多条road,这些road的cost可能相同也可能不同。所以就不能用邻接矩阵存图,因为这样两个office之间只会记录一条边。改成邻接表存图就不会有这个问题。我用邻接矩阵开始过了小数据,大数据incorrect。还以为是溢出了,最后是通过看large input data+对拍找出来的。/(ㄒoㄒ)/~~

#include<iostream>#include<stdio.h>#include<cstdio>#include<string>#include<cmath>#include<stdlib.h>#include<algorithm>#include<string.h>#include<cstring>#include<vector>#include<queue>#include<map>#include<set>using namespace std;//2016 Round A Problem C. gCampusint T;const int maxn=110;int M;int N;pair<int,int>road[10010];long long dis[maxn];//arriving time=S+distanceconst long long INF=1e18;bool vis[maxn];bool efficient[10010];//int edgeidx[maxn][maxn];class node{public:    int neighbor;    int cost;    int index;    node()    {        neighbor=0;        cost=0;        index=0;    }    node(int n,int c,int i)    {        neighbor=n;        cost=c;        index=i;    }};vector<node>mp[maxn];class ComparisonClass{public:    bool operator()(pair<long long,int>a,pair<long long,int>b)    {        if(a.first==b.first)        {            return a.second>b.second;//second is index        }        return a.first>b.first;//first is distance    }};void shortest(int st){    //memset(dis,0x3f,sizeof(dis));    for(int i=0;i<N;i++)    {        dis[i]=INF;    }    memset(vis,false,sizeof(vis));//    memset(pre,0,sizeof(pre));    dis[st]=0;    //pre[st]=-1;    priority_queue<pair<long long,int>,vector<pair<long long,int> >,ComparisonClass> que;    que.push(make_pair(0,st));    while(!que.empty())    {        pair<long long,int>now=que.top();        vis[now.second]=true;        que.pop();       // cout<<"cur "<<now.second<<endl;        for(int i=0;i<mp[now.second].size();i++)        {            int neigh=mp[now.second][i].neighbor;            //if(mp[now.second][i]==0) continue;            if(vis[neigh]==true) continue;            if(dis[neigh]>now.first+mp[now.second][i].cost)            {                dis[neigh]=now.first+mp[now.second][i].cost;                //pre[i]=now.second;                //cout<<"update "<<i<<" "<<pre[i]<<endl;//                if(st==0&&i==2)//                {//                    cout<<now.second<<" "<<now.first<<" "<<mp[now.second][i]<<endl;//                }                pair<long long,int>tmp=make_pair(dis[neigh],neigh);                que.push(tmp);            }        }    }//    if(st!=0) return;//    for(int i=0;i<N;i++)//    {//        cout<<dis[i]<<endl;////        cout<<"ed "<<i<<" "<<dis[i]<<endl;//    }}//void findallroads(int st)//{//    for(int ed=0;ed<N;ed++)//    {//        if(st==ed) continue;//        int node=ed;//        while(pre[node]!=-1)//        {//            //cout<<node<<" "<<pre[node]<<endl;//            used.insert(make_pair(min(node,pre[node]),max(node,pre[node])));//            node=pre[node];//        }//    }//}void findallroads(){    for(int i=0;i<N;i++)    {        for(int j=0;j<mp[i].size();j++)        {            int neigh=mp[i][j].neighbor;            if(dis[i]+mp[i][j].cost==dis[neigh])            {                efficient[mp[i][j].index]=true;                //used.insert(make_pair(min(i,j),max(i,j)));            }        }    }}int main(){    freopen("C-large-practice.in","r",stdin);//    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d",&T);    for(int ca=1;ca<=T;ca++)    {        scanf("%d %d",&N,&M);        memset(mp,0,sizeof(mp));        memset(efficient,false,sizeof(efficient));//        used.clear();        for(int i=0;i<M;i++)        {            int U=0;            int V=0;            int C=0;            scanf("%d %d %d",&U,&V,&C);            mp[U].push_back(node(V,C,i));            mp[V].push_back(node(U,C,i));//            if(mp[U][V]==0)//(U,V) may have multiple input cost, use adjacent vector instead//            {//                mp[U][V]=C;//                edgeidx[U][V]=i;//            }//            else//            {//                cout<<U<<" "<<V<<" "<<C<<" "<<mp[U][V]<<endl;//                if(C<mp[U][V])//                {//                    mp[U][V]=C;//                    edgeidx[U][V]=i;//what if (U,V) is connected by two roads with same cost?//                }//                //mp[U][V]=min(mp[U][V],C);//            }//            if(mp[V][U]==0)//            {//                mp[V][U]=C;//                edgeidx[V][U]=i;//            }//            else//            {//                if(C<mp[V][U])//                {//                    mp[V][U]=C;//                    edgeidx[V][U]=i;//                }//                //mp[V][U]=min(mp[V][U],C);//            }//            if(U==0&&V==2) cout<<U<<" "<<V<<" "<<mp[U][V]<<endl;//            if(U==2&&V==0) cout<<U<<" "<<V<<" "<<mp[U][V]<<endl;            //road[i]=make_pair(min(U,V),max(U,V));            //set.insert(make_pair(min(U,V),max(U,V)));        }        //cout<<N<<endl;        printf("Case #%d:\n",ca);        for(int i=0;i<N;i++)        {            //cout<<i<<endl;            shortest(i);            findallroads();        }        //int cnt=0;        for(int i=0;i<M;i++)        {            if(efficient[i]==false)            {                printf("%d\n",i);            }//            if(used.find(road[i])==used.end())//            {//                //ineff[cnt++]=i;//                printf("%d\n",i);//            }        }    }    return 0;} 

0 0
原创粉丝点击