zoj3946 Highway Project (優先隊列xjb搞)

           浙江省第13屆省賽K題

           題意:要修建m條路,修每條路花費Ci dollars,經過這條路需要Di分鐘,求從0結點到其他n-1個節點的時間最小且修路花費最小。

           思路:從0結點開始往外拓展,把與其相關的點加入隊列裏面,找到從0能到達的時間最短的點a,標記了,再把與其相關的未訪問的結點加入隊列,,其時間要加上到達a的時間,這樣繼續下去,其實就是每次找已標記的點所能到達的最近的點並將其標記,直到把所有點標記。

          詳細見代碼:

#include<iostream>
#include<cstdio>
#include<set>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef unsigned long long LLu;
typedef long long LL;
const int maxn=2*1e5+100;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int MOD = 1e9+7;
struct node
{
	int to;
	LL t,c;
};
bool operator < (node a,node b)
{
	return a.t<b.t||(a.t==b.t&&a.c<b.c);
}
int head[maxn];
bool vis[maxn];
int Next[maxn];
node info[maxn];
int tot;
void init()
{
	memset(head,-1,sizeof head);
	memset(vis,true,sizeof vis);
	tot=0;
}
void add(LL fr,LL to,LL t,LL c)
{
	Next[tot]=head[fr];
	info[tot].to=to;
	info[tot].t=t;
	info[tot].c=c;
	head[fr]=tot++;
}
priority_queue<node >q;
void bfs()
{
	vis[0]=false;
	LL time=0;LL doll=0;
	int i;
	for( i=head[0];i!=-1;i=Next[i])
	{
		node b=info[i];
		b.t=-b.t;
		b.c=-b.c;
		q.push(b);
	}
	while(!q.empty())
	{
		node a=q.top();
		q.pop();
//		printf("%d \n",a.to);
		if(!vis[a.to]) continue;
		vis[a.to]=false;
		time=time+a.t;
		doll=doll+a.c;
		for(i=head[a.to];i!=-1;i=Next[i])
		{
			node b=info[i];
			if(!vis[b.to]) continue;
			b.t=-b.t+a.t;
			b.c=-b.c;
			q.push(b);
//			printf("%d df\n",b.to);
		}
	}
	printf("%lld %lld\n",-time,-doll);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		int i,j,k;
		LL x,y,d,c;
		init();
		for(i=1;i<=m;i++)
		{
			scanf("%lld%lld%lld%lld",&x,&y,&d,&c);
			add(x,y,d,c);
			add(y,x,d,c);
		}
//		cout<<m<<endl;
		bfs();
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章