标签:des style blog http io color os ar java
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
2 10 20 30 1 3 2 2 4 1 1 2 2 1 2 0 0 0 0
【Sample Output】
30
【题意】
有一个村庄需要修建供水系统。每户居民的房子都有一个三维坐标,每户居民可以选择自己挖井或者从其他居民家里引水。挖水井和引水分别需要花费不同的钱。每户居民有一个意愿表,只愿意对表内的居民家供水。最后要求计算出能为所有居民供水的最小花费。
【分析】
本题具有明显的方向性,如果把供水用一条有向边表示的话,很明显能够发现本题抽象到最后是一个最小树形图。
因此思路就明确了,求解最小树形图可以直接套模板,需要做的就是根据题目条件来建图。
这里没有指定水源从哪来,但是至少是需要有1户人家挖水井才能有水。因此首先用0表示虚节点,从虚节点向所有人家连有向边,边长即为每户人家挖水井需要的花费,然后根据每户人家的意愿表加入有向边,处理一下边权。
最后套一个模板求解即可。
1 /* *********************************************** 2 MYID : Chen Fan 3 LANG : G++ 4 PROG : HDU 4009 5 ************************************************ */ 6 7 #include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 12 using namespace std; 13 14 const int N = 1010; 15 const int M = N*N; 16 typedef struct nod 17 { 18 int a,b,c; 19 } node; 20 node edge[M]; 21 int predge[N],id[N],visit[N],in[N]; 22 int dmst(int root,int n,int m)//n表示点数,m表示边数,root表示根 23 { 24 int u,v; 25 int ret=0; 26 while(true) 27 { 28 for(int i=0;i<n;i++) in[i]=INT_MAX; 29 for(int i=0;i<m;i++) 30 { 31 if(edge[i].c<in[edge[i].b]&&edge[i].a!=edge[i].b) 32 { 33 predge[edge[i].b]=edge[i].a;//找出每个点的最小入弧 34 in[edge[i].b]=edge[i].c; 35 } 36 } 37 for(int i=0;i<n;i++) 38 { 39 if(i==root) continue; 40 if(in[i]==INT_MAX) return -1; 41 } 42 in[root]=0; 43 int cnt=0; 44 memset(id,-1,sizeof(id)); 45 memset(visit,-1,sizeof(visit)); 46 for(int i=0;i<n;i++) 47 { 48 ret+=in[i];//进行缩圈 49 v=i; 50 while(visit[v]!=i&&id[v]==-1&&v!=root) 51 { 52 visit[v]=i; 53 v=predge[v]; 54 } 55 if(v!=root&&id[v]==-1) 56 { 57 for(u=predge[v];u!=v;u=predge[u]) 58 id[u]=cnt; 59 id[v]=cnt++; 60 } 61 } 62 if (cnt==0) break; 63 for (int i=0;i<n;i++) 64 if (id[i]==-1) id[i]=cnt++; 65 for (int i=0;i<m;i++) 66 { 67 v=edge[i].b;//进行缩点,重新标记。 68 edge[i].a=id[edge[i].a]; 69 edge[i].b=id[edge[i].b]; 70 if (edge[i].a!=edge[i].b) edge[i].c-=in[v]; 71 } 72 n=cnt; 73 root=id[root]; 74 } 75 return ret; 76 } 77 78 typedef struct hnod 79 { 80 int x,y,z; 81 } hnode; 82 hnode house[N]; 83 84 int dis(int x,int y) 85 { 86 return abs(house[x].x-house[y].x)+abs(house[x].y-house[y].y)+abs(house[x].z-house[y].z); 87 } 88 89 int main() 90 { 91 int n,x,y,z; 92 scanf("%d%d%d%d",&n,&x,&y,&z); 93 while (n||x||y||z) 94 { 95 for (int i=1;i<=n;i++) 96 scanf("%d%d%d",&house[i].x,&house[i].y,&house[i].z); 97 int tot=0; 98 for (int i=1;i<=n;i++) 99 { 100 int p; 101 scanf("%d",&p); 102 for (int j=1;j<=p;j++) 103 { 104 int d; 105 scanf("%d",&d); 106 edge[tot].a=i; 107 edge[tot].b=d; 108 edge[tot].c=dis(i,d)*y; 109 if (house[i].z<house[d].z) edge[tot].c+=z; 110 tot++; 111 } 112 } 113 for (int i=1;i<=n;i++) 114 { 115 edge[tot].a=0; 116 edge[tot].b=i; 117 edge[tot].c=house[i].z*x; 118 tot++; 119 } 120 121 printf("%d\n",dmst(0,n+1,tot)); 122 123 scanf("%d%d%d%d",&n,&x,&y,&z); 124 } 125 126 return 0; 127 }
标签:des style blog http io color os ar java
原文地址:http://www.cnblogs.com/jcf94/p/4067363.html