トピックリンク:
ポータル
タイトルの説明:
市政府の「Benefitingthe People Project」の目標は、市内のnの住宅地域間にガスパイプラインを設置することです(ただし、パイプラインを介して間接的に到達できる限り、パイプラインで直接接続されている必要はありません)。明らかに、最大でn(n-1)/ 2のパイプラインを建設できますが、実際には、nの住宅地を接続するために建設する必要があるのはn-1のパイプラインだけです。次に、利益をもたらすプロジェクトの最小コストを計算するプログラムを作成してください。
入力:
テスト入力には、いくつかのテストケースが含まれています。各テストケースの最初の行は、住宅用サイトの数M(<= 100)と評価されたパイプラインの数Nを示します。後続のN行は、住宅用サイト間のパイプラインのコストに対応し、各行は正の整数のペアを示します。 、それぞれ2つの決済の数と2つの決済間のパイプラインのコスト(これも正の整数)。簡単にするために、集落には1からMまでの番号が付けられています。
出力:
各テストケースについて、都市のパイプラインのスムーズな流れに必要な最低コストを1行で出力します。統計データがスムーズな流れを保証するのに十分でない場合は、「?」を出力します。
サンプル入力:
3 3
1 2 1
1 3 2
2 3 4
3 1
2 3 2
サンプル出力:
3
?
プリムアルゴリズムc参照コード:
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
#define MAX 101
int m,n;
int cost[MAX][MAX];
int dist[MAX];
int visited[MAX];
void prim()
{
memset(visited,0,sizeof(visited));
int i,j,sum=0;
for(i=1;i<=m;i++)
dist[i]=cost[1][i];
visited[1]=1;
for(i=1;i<m;i++)
{
int min=INF,pos=-1;
for(j=1;j<=m;j++)
{
if(visited[j]==0&&dist[j]<min)
{
min=dist[j];
pos=j;
}
}
if(pos!=-1)
{
visited[pos]=1;
sum+=min;
}
else
break;
for(j=1;j<=m;j++)
{
if(visited[j]==0&&dist[j]>cost[pos][j])
dist[j]=cost[pos][j];
}
}
for(i=1;i<=m;i++)
{
if(visited[i]==0)
break;
}
if(i==m+1)
printf("%d\n",sum);
else
printf("?\n");
}
int main()
{
int i,x,y,z;
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(cost,INF,sizeof(cost));
for(i=1;i<=m;i++)
cost[i][i]=0;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
cost[x][y]=cost[y][x]=z;
}
prim();
}
return 0;
}
クラスカルアルゴリズムc参照コード:
#include <stdio.h>
#include <stdlib.h>
#define MAX 101
int n,m;
int parent[MAX];
typedef struct{
int u,v;
int w;
}Tube,*tube;
Tube a[4951];
int cmp(const void *a,const void *b)
{
tube pa=(tube)a;
tube pb=(tube)b;
int num1=pa->w;
int num2=pb->w;
return num1-num2;
}
void init()
{
int i;
for(i=1;i<=m;i++)
parent[i]=i;
}
int find(int x)
{
if(x==parent[x])
return x;
else
return parent[x]=find(parent[x]);
}
void kruskal()
{
qsort(a,n,sizeof(Tube),cmp);
int i,sum=0,count=0;
for(i=0;i<n;i++)
{
int A=find(a[i].u);
int B=find(a[i].v);
if(A!=B)
{
parent[A]=B;
sum+=a[i].w;
}
}
for(i=1;i<=m;i++)
{
if(parent[i]==i)
count++;
}
if(count==1)
printf("%d\n",sum);
else
printf("?\n");
}
int main()
{
int i;
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
for(i=0;i<n;i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
kruskal();
}
return 0;
}