Tree
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2107 Accepted Submission(s): 610
Problem Description
There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and B whose value of happiness are VA and VB,if VA is a prime number,or VB is a prime number or (VA+VB) is a prime number,then they can be connected.What's more,the cost to connecte two cities is Min(Min(VA , VB),|VA-VB|).
Now we want to connecte all the cities together,and make the cost minimal.
Now we want to connecte all the cities together,and make the cost minimal.
Input
The first will contain a integer t,followed by t cases.
Each case begin with a integer N,then N integer Vi(0<=Vi<=1000000).
Each case begin with a integer N,then N integer Vi(0<=Vi<=1000000).
Output
If the all cities can be connected together,output the minimal cost,otherwise output "-1";
Sample Input
2 5 1 2 3 4 5 4 4 4 4 4
Sample Output
4 -1建图比较难,其他比较模板!代码:库鲁斯卡尔:#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; #define N 1100 #define INF 0x3f3f3f3f int a[N],prime[1000000+100],set[N]; struct node { int strart; int end; int dist; }num[370000]; bool cmp (node a,node b) { return a.dist<b.dist ; } void dabiao()//打表,以免超时 { int i,j; memset(prime,0,sizeof(prime)); for(i=2;i<1000000+100;i++) { if(!prime[i]) for(j=2*i;j<1000000+100;j+=i) prime[j]=1; } prime[1]=1; } int find(int p) { int temp,child=p; while(p!=set[p]) p=set[p]; while(child!=p) { temp=set[child]; set[child]=p; child=temp; } return p; } void merge(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) set[fx]=fy; } int minxe(int a,int b,int c) { if(a>b) a=b; if(a>c) a=c; return a; } int main() { int t; scanf("%d",&t); dabiao(); while(t--) { int i,j,k=1,n,outcome=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { num[k].strart =i; num[k].end =j; if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]]) { num[k].dist=minxe(a[i],a[j],abs(a[i]-a[j])); } else num[k].dist =INF; k++; } sort(num,num+k,cmp); for(i=1;i<=n;i++) set[i]=i; int flag=1; for(i=1;i<k;i++) { if(find(num[i].strart )!=find(num[i].end )) { if(num[i].dist ==INF) { flag=0; break; } outcome+=num[i].dist ; merge(num[i].strart ,num[i].end ); } } if(!flag) { printf("-1\n"); continue; } if(outcome>=INF) printf("-1\n"); else printf("%d\n",outcome); } return 0; }
普里姆:#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #define INF 0x3f3f3f #define N 1100 int a[N],n; int map[N][N],prime[1000000+100]; void dabiao()//打表求素数 { int i,j,k; memset(prime,0,sizeof(prime)); for(i=2;i<1000000+100;i++) { if(!prime[i]) for(j=2*i;j<1000000+100;j+=i) prime[j]=1; } prime[1]=1; } int min(int a,int b,int c)//求最小值 { if(a>b) a=b; if(a>c) a=c; return a; } void prim()//求最小树 { int mincost,next=0,i,j,k,result=0; int visit[N],cost[N]; memset(visit,0,sizeof(visit)); for(i=0;i<n;i++) { cost[i]=map[0][i]; } visit[0]=1; for(i=1;i<n;i++) { mincost=INF,next=0; for(j=0;j<n;j++) { if(!visit[j]&&cost[j]<mincost) { mincost=cost[j]; next=j; } } if(!next) { printf("-1\n"); return ; } visit[next]=1; result+=mincost; for(j=0;j<n;j++) { if(!visit[j]&&cost[j]>map[next][j]) cost[j]=map[next][j]; } } if(result) printf("%d\n",result); else printf("-1\n"); } int main() { int t; scanf("%d",&t); dabiao(); while(t--) { int i,j,k; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<n;i++) { map[i][i]=0; for(j=i+1;j<n;j++) { if(!prime[a[i]]||!prime[a[j]]||!prime[a[i]+a[j]]) map[i][j]=map[j][i]=min(a[i],a[j],abs(a[i]-a[j])); else map[i][j]=map[j][i]=INF; } } prim(); } return 0; }