poj 1861 Network

来源:互联网 发布:excel表格数据分析 编辑:程序博客网 时间:2024/04/20 14:23
Memory: 4124KTime: 110MSLanguage: C++Result: Accepted

一开始理解错题意了。。把P当作是最小生成树的总权值,应该是构成最小生成树的点的个数!郁闷,查了老久,就是没往题意上想。。。

#include<stdio.h>
#define INT_MAX 100000001
const int MAXN=1001;
int  arr[MAXN][MAXN]; 
int  used[MAXN];
int ans[MAXN][2];
int max,t;
 //prime:每次都从剩下的边中选出最短的一条,标记相关的顶点,并且修改相关边的值


struct point
{
int x;
int y;
int val;
int flag;
}dis[MAXN];
 
void prim(int n) 
{
int v,min;
int i,j;
for(i=1;i<=n;i++) //先默认第一个为待选节点
{
dis[i].flag=0; 
dis[i].val=arr[1][i];
dis[i].x=1;
dis[i].y=i;
dis[1].flag=1;  
t=0;
while(1)
{
min=INT_MAX;
v=0; 
for(i=1;i<=n;i++) 
if(!dis[i].flag && dis[i].val<min) //在待选节点中选出最小
{
min=dis[i].val; 
v=i;
ans[t][0]=dis[i].x;
       ans[t][1]=dis[i].y;
if(v==0)
break;
t++;
if(min>max)
max=min;
            dis[v].flag=1;
for(j=1;j<=n;j++) 
if(!dis[j].flag && dis[j].val>arr[v][j])
{
//新引入的顶点到其他顶点的边值是否小于原来的边值   
dis[j].val=arr[v][j];
dis[j].x=v;
dis[j].y=j;
}
}
}                   


int main() 
{
int n,q,i,j,a,b,c;
while(scanf("%d%d",&n,&q)==2)
{
for(i=1;i<=n;i++) 
for(j=1;j<=n;j++) 
arr[i][j]=INT_MAX;
        max=-1;
for( i=1;i<=q;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<arr[a][b])
   arr[a][b]=arr[b][a]=c;
}
prim(n); 
printf("%d\n%d\n",max,t); 
for(i=0;i<t;i++)
printf("%d %d\n",ans[i][0],ans[i][1]);
}   
return 0; 
}