POJ 1511Invitation Cards
题意:给你一些边和点的关系,要你从1出发到其它点距离之和的最短路加上从其他点到1最短路的和,这题明显的正向图和反向图,spfa+前向星能AC,但是用dij+优先队列的话配上前向星理论上能过,但是别用vector,因为数据太大会炸内存,其他就是模板了;
#include<algorithm> #include<iostream> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #include<cstdio> #include<cstring> #define INF 0x3f3f3f3f using namespace std; typedef struct node { int x; int y; int date; } node; node s[1000005]; long long dis[1000005]; bool vis[1000005]; int first[1000005]; int first_a[1000005]; int next_a[1000005]; int next[1000005]; int main() { int m; scanf("%d",&m); int n,k; for(int i=1; i<=m; i++) { scanf("%d%d",&n,&k); int a,b,c; for(int j=1; j<=n; j++) { first[j]=-1; first_a[j]=-1; } for(int j=1; j<=k; j++) { scanf("%d%d%d",&s[j].x,&s[j].y,&s[j].date); next[j]=first[s[j].x]; first[s[j].x]=j; next_a[j]=first_a[s[j].y]; first_a[s[j].y]=j; // cout<<next_a[j]<<" "<<first_a[s[j].y]<<endl; } memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; vis[1]=1; queue<int>que; que.push(1); while(!que.empty()) { int p=que.front(); que.pop(); vis[p]=0; for(int j=first[p]; j!=-1; j=next[j]) { if(dis[s[j].y]>dis[s[j].x]+s[j].date) { dis[s[j].y]=dis[s[j].x]+s[j].date; if(vis[s[j].y]==0) { vis[s[j].y]=1; que.push(s[j].y); } } } } long long sum=0; for(int j=2; j<=n; j++) { sum+=dis[j]; } memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; vis[1]=1; que.push(1); while(!que.empty()) { int p=que.front(); que.pop(); vis[p]=0; for(int j=first_a[p]; j!=-1; j=next_a[j]) { if(dis[s[j].x]>dis[s[j].y]+s[j].date) { dis[s[j].x]=dis[s[j].y]+s[j].date; if(vis[s[j].x]==0) { vis[s[j].x]=1; que.push(s[j].x); } } } } for(int j=2; j<=n; j++) { sum+=dis[j]; } cout << sum<<endl; } return 0; }