HDU ACM 1535 Invitation Cards单点到多源最短路->SPFA算法

题意:有一个起始站点,从这里送n个学生去其余的n-1个站点邀请人们去CSS,然后再返回CSS,使得总的花费最小。注意每次只能送一个,返回时每次也只能送一个,而且每条路是单向的。

分析:这相当于一个有向图,我们只需两次调用SPFA算法即可,第一次求出初始站点(在这里是1)到其它所有站点的最小花费,然后相加;第二次将图反向建立,即所有的边反向,再求出初始站点(这里是1)到其它站点的最小费用,之后相加,第二步的图反向后按照第一次的求法就相当于从其它所有点到初始点的最小距离,因为算法只能求单点到多点而不能求多点到单点。最后把两次的结果相加即可得到最终结果。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

int u[1000001];
int v[1000001];
int w[1000001];
bool vis[1000001];
int d[1000001];
int first[1000001];
int Next[1000001];

void InitAndInput(int n,int m)    //输入图
{
	int i;

	for(i=1;i<=n;i++)
		first[i]=-1;

	for(i=0;i<m;i++)
		Next[i]=-1;

	for(i=0;i<m;i++)
	{
		cin>>u[i]>>v[i]>>w[i];
		Next[i]=first[u[i]];
		first[u[i]]=i;
	}
}

void InverseBulid(int n,int m)    //反向建立图
{
	int i;

	for(i=1;i<=n;i++)
		first[i]=-1;

	for(i=0;i<m;i++)
		Next[i]=-1;

	for(i=0;i<m;i++)
	{
		Next[i]=first[v[i]];
		first[v[i]]=i;
	}
}

void spfa(int n,int s,bool flag)    //flag表示当前处理的是反向建立后的图还是一开始的图,false反向,true开始
{
	queue<int> q;
	int i,x,y;

	for(i=1;i<=n;i++)
		vis[i]=false;

	for(i=1;i<=n;i++)
		d[i]=(i==s)?0:0x7fffffff;   //初始化,自己到自己为0,其他到自己相当于无穷大

	q.push(s);
	while(!q.empty())
	{
		x=q.front();
		q.pop();
		vis[x]=false;
		for(i=first[x];i!=-1;i=Next[i])
		{
			y=flag?v[i]:u[i];
			if(d[y]>d[x]+w[i])
			{
				d[y]=d[x]+w[i];
				if(!vis[y])
				{
					vis[y]=true;
					q.push(y);
				}
			}
		}
	}
}

int main()
{
	int P,Q,N,sum,i;

	cin>>N;
	while(N--)
	{
		sum=0;
		cin>>P>>Q;
		InitAndInput(P,Q);
		spfa(P,1,true);         //正向求出最小和
		for(i=2;i<=P;i++)
			sum+=d[i];
		InverseBulid(P,Q);    //反向建图
		spfa(P,1,false);         //反向求出最小和
		for(i=2;i<=P;i++)
			sum+=d[i];

		cout<<sum<<endl;
	}
    return 0;
}
时间: 2024-10-27 00:03:13

HDU ACM 1535 Invitation Cards单点到多源最短路->SPFA算法的相关文章

hdu 1535 Invitation Cards 大年初一首A 一次正向SPFA+一次逆向SPFA

Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2311    Accepted Submission(s): 1125 Problem Description In the age of television, not many people attend theater performances.

POJ-1511 Invitation Cards (双向单源最短路)

Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all

HDU 1535 Invitation Cards (POJ 1511)

两次SPFA.求 来 和 回 的最短路之和. 用Dijkstra+邻接矩阵确实好写+方便交换,但是这个有1000000个点,矩阵开不了. d1[]为 1~N 的最短路. 将所有边的 邻点 交换. d2[] 为 1~N 的最短路. 所有相加为 所要答案. 忧伤的是用SPFA  "HDU 1535"  AC了,但是POJ 一样的题 "POJ 1511" 就WA了. 然后强迫症犯了,不停的去测试. 题意中找到一句关键话 :Prices are positive integ

hdu 1535 Invitation Cards(有向图的来回最短路,要反向建图)

题目: 链接:点击打开链接 题意: 给一个图,求1到各点和各点到1最短路. 思路: 先spfa,然后反向建图,在spfa就行了. 代码: #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; #define INF 100000000 const int N = 1000010; struct node{ int u,v,w

HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题意: 有向图,求点1到点2-n的最短距离之和以及点2-n到点1的最短距离之和 方法: 1.跑1为原点的最短路 2.反向建图(把有向图的边反向,(u,v,w)变成(v,u,w)),跑1为原点的最短路 3.将两者距离之和加和即可(注意用 long long ,int会溢出) 1 void input() 2 { 3 scanf("%d%d", &n, &m); 4 g1.

hdu 1535 Invitation Cards(SPFA)

Invitation Cards Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submission(s) : 28   Accepted Submission(s) : 14 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description In the age of telev

HDU - 1535 Invitation Cards 前向星SPFA

Invitation Cards In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards wit

hdu 1535 Invitation Cards

#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int inf=1<<24; const int N=1000000+5; struct node { int to,w; node* next; }; node* edge[N]; node* reedge[N]; int n,m,x,dist[N

HDU ACM 2586 How far away ?LCA-&gt;并查集+Tarjan(离线)算法

题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w,有m次询问,每次询问房子a,b之间的距离是多少. 分析:最近公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次询问a,b之间的距离=d[a]+d[b]-2*d[LCA(a,b)];LCA(a,b)是a,b的最近公共祖先. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include