您的位置:首页 > 其它

图论——昂贵的聘礼

2016-02-04 16:58 267 查看
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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: