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
- Problem C. gCampus Google APAC 2016 University Test Round A
- Round A APAC Test 2016 Problem C. gCampus 最短路
- Problem A. gRanks Google APAC 2016 University Test Round C
- Problem A. Travel Google APAC 2016 University Test Round B
- Problem B. gCube Google APAC 2016 University Test Round A
- Problem D. gMatrix Google APAC 2016 University Test Round C
- Problem B. gFiles Google APAC 2016 University Test Round C
- Problem C. gNumbers Google APAC 2016 University Test Round B
- Problem A. Vote Google APAC 2017 University Test Round D
- Problem B. Rain Google APAC 2017 University Test Round A
- Problem C. Evaluation Google APAC 2017 University Test Round C
- Problem D. Soldiers Google APAC 2017 University Test Round C
- Problem C. Jane's Flower Shop Google APAC 2017 University Test Round A
- Problem A. Monster Path Google APAC 2017 University Test Round C
- Problem A. Googol String Google APAC 2016 University Test Round A
- Problem B. gBalloon Google APAC 2016 University Test Round D
- Problem B. gWheels Google APAC 2016 University Test Round B
- Google APAC 2017 University Test Round A
- 单调队列
- 欢迎使用CSDN-markdown编辑器
- Linux程序编译链接动态库版本的问题
- Linux 的虚拟文件系统
- LeetCode-Remove K Digits 去掉K位数字
- Problem C. gCampus Google APAC 2016 University Test Round A
- 【并发编程】当我们谈论线程安全时我们在谈论什么
- 算法粗略见解
- Linux make笔记
- 习题30 else 和 if. 附加练习3
- 一种基于中值滤波的轨迹纠偏方法和几点思考
- JAVA多线程实现的四种方式
- Leetcode 365
- Majority Element