图论——昂贵的聘礼

nkoj 2226

一道很好的图论dijstra算法应用题。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int inf=2e9;
queue<int>q;
int m,n,pos[105],dist[105],map[105][105];
bool vis[105];
void input(){
	int i,j,x,y,t;
	scanf("%d%d",&m,&n);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
		   if(i!=j)map[i][j]=inf;
	for(i=1;i<=n;i++){   //每件物品 
		scanf("%d%d%d",&t,&pos[i],&x);
		map[0][i]=t;
		while(x--){   //优惠 
			scanf("%d%d",&y,&t);
			map[y][i]=t;
		}
	}
}
int dijstra(int minn,int maxx){    //枚举地位从minn到maxx的人 
	int i,x;
	memset(vis,0,sizeof(vis));    //别忘了清零 
	for(i=1;i<=n;i++)dist[i]=map[0][i];
	dist[0]=0;vis[0]=true;
	do{
		int k=inf;
		x=0; 
		for(i=1;i<=n;i++)
		if(!vis[i]&&dist[i]<k&&pos[i]>=minn&&pos[i]<=maxx) //条件:地位适合 
		k=dist[i],x=i;
		if(x>0){
			vis[x]=true;
		    for(i=1;i<=n;i++)
				dist[i]=min(dist[i],dist[x]+map[x][i]);  //更新dist 
	}
	}while(x>0);
	return dist[1];
}
void solve(){
	int ans=map[0][1];
	for(int i=pos[1]-m;i<=pos[1];i++)  //依次枚举每个区间 
	ans=min(dijstra(i,i+m),ans);
	printf("%d",ans);
}
int main(){
	input();
	solve();
}

你可能感兴趣的:(图论——昂贵的聘礼)