现在的位置: 首页 > 算法 > 正文

poj 1511,zoj 2008

2018年12月31日 算法 ⁄ 共 1228字 ⁄ 字号 评论关闭

题意:n-1个ACM学生自愿者每天要从css(1站点)坐车到达剩下站点,每个人去一个站点,

到一天结束时要返回到css(1站点),城市的交通系统是有向图,求n-1个学生车费最少。

分析:当学生去的时候相当于求点1到所有点的最短路。回来时,是求所有点到1的最短路,

数据很大肯定不能每个点求一次,建反图后就是求1到搜有点的最短路了,用dijkstra()可以解决,

数据太大,用dijkstra()+优先队列,总结果会超int,wrong了几次,,,,,,





#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#define N 1000001
#define inf 0x3fffffff
using namespace std;
int n,m,vis[N];
long long sum;
struct edge
{
	struct edge *next;
	int end,w;
}*e[N],*ce[N];//ce:反图
struct node
{
	int s;
	int w;
	friend bool operator < (node a, node b) 
	{
		return a.w>b.w;  
	}
};
void addedge(int x,int y,int w)
{
	edge *p=new(edge),*q=new(edge);
	p->next=e[x];q->next=ce[y];
	p->end=y;    q->end=x;
	p->w=w;    q->w=w;
	e[x]=p;    ce[y]=q;
}
void dijkstra(struct edge **q)
{
	priority_queue<node> Q;
	int num=0;
	node cur,next;
	cur.s=1;
	cur.w=0;
	Q.push(cur);
	memset(vis,0,sizeof(vis));
	while(!Q.empty())
	{
		cur=Q.top();
		Q.pop();
		if(vis[cur.s]==1)continue;//点被标记了,就不往下进行了
		vis[cur.s]=1;
		sum+=cur.w;
		num++;
		if(num==n)break;
		for(struct edge *p=q[cur.s];p;p=p->next)
		{
			next.s=p->end;
			next.w=p->w+cur.w;
			if(vis[next.s]==0)
				Q.push(next);
		}		
	}
}
int main()
{
	int j,x,y,w,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		memset(e,NULL,sizeof(e));
		memset(ce,NULL,sizeof(ce));
		for(j=0;j<m;j++)
		{
			scanf("%d%d%d",&x,&y,&w);
			addedge(x,y,w);
		}
		sum=0;
		dijkstra(e);
		dijkstra(ce);
		printf("%lld\n",sum);		
	}
	return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.