[USACO3.2.6]Sweet Butter

来源:互联网 发布:正品潮牌代购淘宝店 编辑:程序博客网 时间:2024/05/22 03:08

Sweet Butter

Greg Galperin -- 2001

Farmer John has discovered the secret to making the sweetest butter in all of Wisconsin: sugar. By placing a sugar cube out in the pastures, he knows the N (1 <= N <= 500) cows will lick it and thus will produce super-sweet butter which can be marketed at better prices. Of course, he spends the extra money on luxuries for the cows.

FJ is a sly farmer. Like Pavlov of old, he knows he can train the cows to go to a certain pasture when they hear a bell. He intends to put the sugar there and then ring the bell in the middle of the afternoon so that the evening's milking produces perfect milk.

FJ knows each cow spends her time in a given pasture (not necessarily alone). Given the pasture location of the cows and a description of the paths that connect the pastures, find the pasture in which to place the sugar cube so that the total distance walked by the cows when FJ rings the bell is minimized. FJ knows the fields are connected well enough that some solution is always possible.

PROGRAM NAME: butter

INPUT FORMAT

  • Line 1: Three space-separated integers: N, the number of pastures: P (2 <= P <= 800), and the number of connecting paths: C (1 <= C <= 1,450). Cows are uniquely numbered 1..N. Pastures are uniquely numbered 1..P.
  • Lines 2..N+1: Each line contains a single integer that is the pasture number in which a cow is grazing. Cow i's pasture is listed on line i+1.
  • Lines N+2..N+C+1: Each line contains three space-separated integers that describe a single path that connects a pair of pastures and its length. Paths may be traversed in either direction. No pair of pastures is directly connected by more than one path. The first two integers are in the range 1..P; the third integer is in the range (1..225).

SAMPLE INPUT (file butter.in)

3 4 52341 2 11 3 52 3 72 4 33 4 5

INPUT DETAILS

This diagram shows the connections geometrically:
          P2   P1 @--1--@ C1     \    |\      \   | \       5  7  3        \ |   \         \|    \ C3       C2 @--5--@          P3    P4

OUTPUT FORMAT

  • Line 1: A single integer that is the minimum distance the cows must walk to a pasture with a sugar cube.

SAMPLE OUTPUT (file butter.out)

8OUTPUT DETAILS:Putting the cube in pasture 4 means: cow 1 walks 3 units; cow 2 walks 5units; cow 3 walks 0 units -- a total of 8.
题目描述:
就是给你一些点,有些点有牛,还有一些路,路有边权,找到一个点,使得所有牛走到这个点的距离和最小。
算法:
可怜我最早竟然想到了什么最小生成树+树形DP,还好还没编就发现了错误。
容易发现是最短路,还是多源的(可以把起点看成终点,然后每个点扫描一遍,算上dist+cownum,求和即可。
数据有点大,所以floyd不行,可能可以用SPFA,这里写了DIJKSTRA+优先队列优化。
(英语不好,但是图看是看得懂的哈哈哈)
我承认,我的堆优化是log m级别的。反正不会超。
——————————————————————————————————————————第一次提交答案错了呀————————————
哦——堆优DJ找到一个点之后没有标记找到了。。嗯,果然不如大佬,连的少。
/*ID:cqz15311LANG:C++PROG:butter*/#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>#include<queue>using namespace std;const int maxe = 1455*2;const int maxv = 805;const int oo = 1<<20;struct Node{int id,val;bool operator < (const Node &x) const{return val > x.val; }};struct E{int to,nxt,dist;}edge[maxe];int first[maxv],nume,Ans,cow[maxv];int dist[maxv];int n,p,c,x;void add_edge(int a,int b,int c){edge[nume] . to = b;edge[nume] . dist = c;edge[nume] . nxt = first[a];first[a] = nume++;}Node f(int x,int y){Node t;t.id = x;t.val = y;return t;}bool vis[maxv];void dijkstra(int s){priority_queue<Node> Heap;memset(dist,0x3f,sizeof(dist));memset(vis,false,sizeof(vis));dist[s] = 0;Heap.push(f(s,0));int u,v;for (int i=1;i<=p-1;i++){Node tmp = Heap.top();Heap.pop();while (vis[tmp . id]){tmp = Heap.top();Heap.pop();}u = tmp . id;vis[u] = true;for (int e=first[u];e!=-1;e=edge[e].nxt){v = edge[e] . to;if (!vis[v]){if (dist[v] > dist[u] + edge[e].dist){dist[v] = dist[u] + edge[e].dist;Heap.push(f(v,dist[v]));}}}}}int main(){freopen("butter.in","r",stdin);freopen("butter.out","w",stdout);scanf("%d%d%d",&n,&p,&c);for (int i=1;i<=n;i++){scanf("%d",&x);cow[x]++;}memset(first,-1,sizeof(first));nume = 0;for (int i=1;i<=c;i++){int a,b,d;scanf("%d%d%d",&a,&b,&d);add_edge(a,b,d);add_edge(b,a,d);}Ans = oo;for (int i=1;i<=p;i++){dijkstra(i);int rec = 0;for (int j=1;j<=p;j++) rec+=dist[j] * cow[j];Ans = min(Ans,rec);}printf("%d\n",Ans);fclose(stdin);fclose(stdout);return 0;}


看看标程:
手写堆!厉害!
#include <stdio.h>#include <string.h>const int BIG = 1000000000;const int MAXV = 800;const int MAXC = 500;const int MAXE = 1450;int cows;int v,e;int cow_pos[MAXC];int degree[MAXV];int con[MAXV][MAXV];int cost[MAXV][MAXV];int dist[MAXC][MAXV];int heapsize;int heap_id[MAXV];int heap_val[MAXV];int heap_lookup[MAXV];bool validheap(void){  for(int i = 0; i < heapsize; ++i){    if(!(0 <= heap_id[i] && heap_id[i] < v)){      return(false);    }    if(heap_lookup[heap_id[i]] != i){      return(false);    }  }  return(true);}void heap_swap(int i, int j){  int s;  s = heap_val[i];  heap_val[i] = heap_val[j];  heap_val[j] = s;  heap_lookup[heap_id[i]] = j;  heap_lookup[heap_id[j]] = i;  s = heap_id[i];  heap_id[i] = heap_id[j];  heap_id[j] = s;}void heap_up(int i){  if(i > 0 && heap_val[(i-1) / 2] > heap_val[i]){    heap_swap(i, (i-1)/2);    heap_up((i-1)/2);  }}void heap_down(int i){  int a = 2*i+1;  int b = 2*i+2;  if(b < heapsize){    if(heap_val[b] < heap_val[a] && heap_val[b] < heap_val[i]){      heap_swap(i, b);      heap_down(b);      return;    }  }  if(a < heapsize && heap_val[a] < heap_val[i]){    heap_swap(i, a);    heap_down(a);  }}int main(){  FILE *filein = fopen("butter.in", "r");  fscanf(filein, "%d %d %d", &cows, &v, &e);  for(int i = 0; i < cows; ++i){    fscanf(filein, "%d", &cow_pos[i]);    --cow_pos[i];  }  for(int i = 0; i < v; ++i){    degree[i] = 0;  }  for(int i = 0; i < e; ++i){    int a,b,c;    fscanf(filein, "%d %d %d", &a, &b, &c);    --a;    --b;    con[a][degree[a]] = b;    cost[a][degree[a]] = c;    ++degree[a];    con[b][degree[b]] = a;    cost[b][degree[b]] = c;    ++degree[b];  }  fclose(filein);  for(int i = 0; i < cows; ++i){    heapsize = v;    for(int j = 0; j < v; ++j){      heap_id[j] = j;      heap_val[j] = BIG;      heap_lookup[j] = j;    }    heap_val[cow_pos[i]] = 0;    heap_up(cow_pos[i]);    bool fixed[MAXV];    memset(fixed, false, v);    for(int j = 0; j < v; ++j){      int p = heap_id[0];      dist[i][p] = heap_val[0];      fixed[p] = true;      heap_swap(0, heapsize-1);      --heapsize;      heap_down(0);      for(int k = 0; k < degree[p]; ++k){int q = con[p][k];if(!fixed[q]){  if(heap_val[heap_lookup[q]] > dist[i][p] + cost[p][k]){    heap_val[heap_lookup[q]] = dist[i][p] + cost[p][k];    heap_up(heap_lookup[q]);  }}      }    }  }  int best = BIG;  for(int i = 0; i < v; ++i){    int total = 0;    for(int j = 0; j < cows; ++j){      total += dist[j][i];    }    best <?= total;  }  FILE *fileout = fopen("butter.out", "w");  fprintf(fileout, "%d\n", best);  fclose(fileout);  return(0);}



原创粉丝点击