標籤:
洛穀1828 香甜的黃油
本題地址: http://www.luogu.org/problem/show?pid=1828
題目描述
農夫John發現做出全威斯康辛州最甜的黃油的方法:糖。把糖放在一片牧場上,他知道N(1<=N<=500)只奶牛會過來舔它,這樣就能做出能賣好價錢的超甜黃油。當然,他將付出額外的費用在奶牛上。
農夫John很狡猾。像以前的Pavlov,他知道他可以訓練這些奶牛,讓它們在聽到鈴聲時去一個特定的牧場。他打算將糖放在那裡然後下午發出鈴聲,以至他可以在晚上擠奶。
農夫John知道每隻奶牛都在各自喜歡的牧場(一個牧場不一定只有一頭牛)。給出各頭牛在的牧場和牧場間的路線,找出使所有牛到達的路程和最短的牧場(他將把糖放在那)
輸入輸出格式
輸入格式:
第一行: 三個數:奶牛數N,牧場數(2<=P<=800),牧場間道路數C(1<=C<=1450)
第二行到第N+1行: 1到N頭奶牛所在的牧場號
第N+2行到第N+C+1行: 每行有三個數:相連的牧場A、B,兩牧場間距離D(1<=D<=255),當然,串連是雙向的
輸出格式:
一行 輸出奶牛必須行走的最小的距離和
輸入輸出範例
輸入範例#1:
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
輸出範例#1:
8
說明
{範例圖形
P2
P1 @[email protected] C1
|
|
5 7 3
|
| C3
C2 @[email protected]
P3 P4
}
{說明:
放在4號牧場最優
}
【思路】
枚舉+最短路。
枚舉放置點,SPFA求出與各個奶牛的距離即可。
【代碼】
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn = 1000+10 ,maxm=1450+10; 8 const int INF=1<<30; 9 struct Edge{10 int v,w,next;11 }e[maxn*maxn];12 int en,front[maxn];13 14 int n,m,C;15 vector<int> cows;16 17 inline void AddEdge(int u,int v,int w) {18 en++; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en;19 }20 21 int SPFA(int s) {22 int inq[maxn],d[maxn];23 queue<int> q;24 memset(inq,0,sizeof(inq));25 for(int i=1;i<=n;i++) d[i]=INF;26 27 d[s]=0; inq[s]=1; q.push(s);28 while(!q.empty()) {29 int u=q.front(); q.pop(); inq[u]=0;30 for(int i=front[u];i>=0;i=e[i].next) {31 int v=e[i].v,w=e[i].w;32 if(d[v]>d[u]+w) {33 d[v]=d[u]+w;34 if(!inq[v]) {35 inq[v]=1;36 q.push(v);37 }38 }39 }40 }41 int ans=0;42 for(int i=0;i<cows.size();i++) ans+=d[cows[i]];43 return ans;44 }45 46 int main() {47 memset(front,-1,sizeof(front));48 scanf("%d%d%d",&C,&n,&m);49 int x;50 for(int i=0;i<C;i++){51 scanf("%d",&x);52 cows.push_back(x);53 }54 int u,v,w;55 for(int i=0;i<m;i++) {56 scanf("%d%d%d",&u,&v,&w);57 AddEdge(u,v,w);58 AddEdge(v,u,w);59 }60 int ans=INF;61 for(int i=1;i<=n;i++) {62 ans=min(ans,SPFA(i));63 }64 printf("%d\n",ans);65 return 0;66 }
洛穀1828 香甜的黃油