【USACO 3.2.6】香甜的黄油
【描述】
农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。
农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。
农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)
【格式】
INPUT FORMAT:
第一行: 三个数:奶牛数N,牧场数P(2<=P<=800),牧场间道路数C(1<=C<=1450)
第二行到第N+1行: 1到N头奶牛所在的牧场号
第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离D(1<=D<=255),当然,连接是双向的
OUTPUT FORMAT:
一行 输出奶牛必须行走的最小的距离和
【分析】
直接上dijkstral+堆就可以了。
1 #include <cstdlib> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdio> 6 #include <queue> 7 #include <stack> 8 #include <ctime> 9 #include <set> 10 #include <vector> 11 const int maxp=800+10; 12 const int INF=10000000; 13 using namespace std; 14 struct edge{int to,w;}; 15 struct node 16 { 17 int num;//编号 18 int dist;//距离 19 bool operator <(const node &b)const 20 { 21 return dist<b.dist; 22 } 23 }; 24 vector<edge>map[maxp]; 25 int cow[maxp]; 26 int n,p,c,low[maxp]; 27 int ans=INF; 28 29 void add_Edge(int u,int v,int w); 30 void dijkstra(int sta); 31 32 int main() 33 { 34 int i,j; 35 //文件操作 36 freopen("data.txt","r",stdin); 37 freopen("out.txt","w",stdout); 38 memset(cow,0,sizeof(cow)); 39 scanf("%d%d%d",&n,&p,&c); 40 41 for (i=1;i<=n;i++) 42 { 43 int u; 44 scanf("%d",&u); 45 cow[u]++;//放置奶牛 46 } 47 for (i=1;i<=c;i++) 48 { 49 int u,v,w; 50 scanf("%d%d%d",&u,&v,&w); 51 add_Edge(u,v,w);//无向边 52 add_Edge(v,u,w); 53 } 54 for (i=1;i<=p;i++) dijkstra(i);//单源最短路 55 printf("%d",ans); 56 return 0; 57 } 58 void dijkstra(int sta) 59 { 60 int i,j,cnt=0,vis[maxp]; 61 priority_queue<pair<int,int> >heap; 62 for (i=1;i<=p;i++) 63 { 64 low[i]=INF; 65 vis[i]=0; 66 }//初始化 67 heap.push(make_pair(0, sta)); 68 low[sta]=0; 69 while (!heap.empty()) 70 { 71 int u=heap.top().second; 72 heap.pop(); 73 if (!vis[u]) 74 { 75 vis[u]=true; 76 for (int i=0; i <map[u].size(); i++) 77 { 78 int v=map[u][i].to,cost; 79 if (!vis[v]) cost=map[u][i].w; 80 if (low[v]>low[u]+cost) 81 { 82 low[v]=low[u]+cost; 83 heap.push(make_pair(-low[v], v)); 84 } 85 } 86 } 87 } 88 //printf("%d:\n",sta); 89 //for (i=1;i<=p;i++) printf("%d ",low[i]); 90 //printf("\n"); 91 for (i=1;i<=p;i++) cnt=cnt+(low[i]*cow[i]); 92 ans=min(ans,cnt); 93 } 94 void add_Edge(int u,int v,int w) 95 { 96 map[u].push_back((edge){v,w}); 97 }