C - 小Y上学记——认识新同学
C - 小Y上学记——认识新同学
Time Limit: 4000/2000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
Problem Description
小Y来到了一个新的班级,新的集体,第一件事肯定是要去认识新同学。
然而想认识全班同学,所需要的代价是很大的,所以小Y想让代价尽可能小。
认识新同学有两种办法,一种是直接去认识,另一种是通过已经认识的同学去认识新同学。
小Y想知道最小代价是多少呢?
Input
多组数据,每组数据首先是一个N,表示新的班级的同学数(包括小Y,2<=N<=1000)
接下来是N-1个整数,表示小Y直接认识第i名同学所需要的代价。
接下来是一个N-1阶矩阵,其中第i行第j列表示通过第i名同学认识第j名同学的代价。
其中保证对角线为0,且保证对称.
所有代价均为不超过1000的正整数。
Output
对于每组数据,输出一个整数,表示最少代价。
Sample Input
3 2 4 0 1 1 0 4 2 4 3 0 1 2 1 0 1 2 1 0
Sample Output
3 4可以转化成最小生成树来求解即可:
代码:2015.7.30(自己写的还是比不上网上大神的模板,唉。。。)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <stdio.h> 3 #include <queue> 4 using namespace std; 5 #define MAX 11010 6 int ID[MAX]; 7 int Sum; 8 struct Node 9 { 10 int a,b,v; 11 friend bool operator <(Node a,Node b) 12 { 13 return a.v>b.v; 14 } 15 }; 16 void Cread(int N) 17 { 18 for(int i=1;i<=N;i++){ID[i]=i;} 19 } 20 int Find(int x) 21 { 22 int TMD=x,TMP; 23 while(TMD!=ID[TMD])TMD=ID[TMD]; 24 while(x!=TMD){TMP=ID[x];ID[x]=TMD;x=TMP;} 25 return x; 26 } 27 int main() 28 { 29 int N,i,j,a,b,A,B,Q,SIGN; 30 Node NUM; 31 while(scanf("%d",&N)!=EOF) 32 { 33 priority_queue<Node>ID_N; 34 Cread(N);Sum=0;SIGN=0; 35 for(i=2;i<=N;i++) 36 { 37 NUM.a=1;NUM.b=i; 38 scanf("%d",&NUM.v); 39 ID_N.push(NUM); 40 } 41 for(i=2;i<=N;i++) 42 { 43 for(j=2;j<=N;j++) 44 { 45 NUM.a=i;NUM.b=j; 46 scanf("%d",&NUM.v); 47 if(i==j)NUM.v=MAX; 48 else ID_N.push(NUM); 49 } 50 } 51 while(!ID_N.empty()) 52 { 53 if(N==SIGN+1)break; 54 NUM=ID_N.top();ID_N.pop(); 55 A=Find(NUM.a);B=Find(NUM.b); 56 if(A!=B) 57 { 58 ID[A]=B; 59 Sum+=NUM.v; 60 SIGN++; 61 } 62 } 63 printf("%d\n",Sum); 64 } 65 return 0; 66 }
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************