zoj 2008 && poj 1511 Invitation Cards

题意:在有向图中求起点到所有点的最短路径长度和所有点到起点的最短路径长度的总和。


思路:

1.起点到所有点的最短路径很好求,直接求单源最短路径即可。

2.所有点到起点的最短路径,如果我们把每一条边都反过来,那么再求一次单源最短路径即可。


注意:

1.poj上的数据超int了,需要用long long。

2.我用cin超时了。。。,换scanf就过了,唉cin还是少用啊。

3.poj 6000ms有点慢。。。


代码:


#include <iostream> 
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const long long inf = 1000000000005;
const int maxn = 1000005;

struct node{
	int index;
	int w;
	
	node(int tindex, int tw){index = tindex; w = tw;}
	
	bool operator < (const node &b) const{
		return w > b.w;
	}
	
};

struct edge{
	int v;
	int w;
	
	edge(int tv, int tw){v = tv; w = tw;}
};

int n,m;
int x[maxn],y[maxn],wi[maxn];
long long dist[maxn];			//Dijkstra算法所需的数组 
bool vis[maxn];
vector<edge> a[maxn]; 	//邻接矩阵

priority_queue<node> q;

void Input() {
	int u,v,w;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= m; i++){
		scanf("%d%d%d",&x[i],&y[i],&wi[i]);
	}
	
}

void Dijkstra(){
	for(int i = 1; i <= n; i++){
		vis[i] = 0;
		dist[i] = inf;		
	}
	
	dist[1] = 0;
	q.push(node(1,0));//初始节点入队 
	while(!q.empty()){
		int u = q.top().index;
		q.pop(); 
		if(vis[u]) continue;
		else vis[u] = 1;
		for(int j = 0; j < a[u].size(); j++){
			int v = a[u][j].v;
			if(!vis[v] && dist[u] + a[u][j].w < dist[v]){
				dist[v] = dist[u] + a[u][j].w;
				q.push(node(v,dist[v]));
			}
		}
	}
}



void Solve(){
	long long sum = 0;
	for(int i = 1; i <= n; i++) a[i].clear();
	for(int i = 1; i <= m; i++) a[x[i]].push_back(edge(y[i],wi[i]));
	Dijkstra();
	for(int i = 1; i <= n; i++){
		sum += dist[i];
	}
	for(int i = 1; i <= n; i++) a[i].clear();
	for(int i = 1; i <= m; i++) a[y[i]].push_back(edge(x[i],wi[i]));
	Dijkstra();
	for(int i = 1; i <= n; i++){
		sum += dist[i];
	}
	printf("%lld\n",sum);
}



int main(){
	int t;
	cin>>t;
	while(t--){
		Input();
		Solve();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值