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;
}

posted @ 2017-10-03 20:25  wang9897  阅读(91)  评论(0编辑  收藏  举报