hdu 1879題解報告

2021-06-20 10:56:15 字數 1777 閱讀 5103

題目大意:給定n個點以及n*(n-1)/2條邊的資訊,然後讓我們求出最短的路程使得所有點相通。

題目解析:其實就是乙個最小生成樹的問題,這裡我用的是prime演算法。

實現**:

#include

#include

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

const int maxn = 150;

const int inf = 0xfffffff;

int n, ans;     //ans為最終答案

int tag[maxn];  //標記陣列,標記第i個頂點是否已經被選擇,1表示已經被選中

int map[maxn][maxn];    //存放邊的權值的資訊,路已建的為0,不通的為無窮遠inf,待建的為某個正值

void addedge(int a, int b, int d, intt){     //新增邊權值的函式

if(t == 0 ) map[a][b] = map[b][a] = d;   

elsemap[a][b] = map[b][a] = 0;

void prime(){     //求解最小生成樹問題的prime演算法

intdist[maxn];   //dist[i]存放第i個頂點到已選點集的最短距離

memset(dist,inf, sizeof(dist));

memset(tag,0, sizeof(tag));

tag[0]= 1;   //第0個點作為源點,自動進入已選點集中

for(inti = 0; i < n; i ++){

dist[i]= map[0][i];   //所有點到已選點集的最短距離dist【i】容易得到

intindex = 0, min;

ans= 0;   //ans記錄的是最小生成樹的所有邊的權值之和

while(1){   //直到所有點都在已選點集中迴圈才終止,即min一直等於inf時

min= inf;

for(intj=1; j < n; j ++){    //掃瞄出此時未選中的點當中最小的dist【i】值

if(!tag[j] && dist[j] < min){

min= dist[j];

index= j;

if(min== inf) break;

tag[index]= 1;  //新選入的點tag改變

ans+= min;       //權值之和增加min值

for(intj = 1; j < n; j ++){    //有新的點被選中後重新重新整理一遍dist陣列

if(map[index][j]< dist[j]) dist[j] = map[index][j];

int main()

inta, b, dis, t;

while(scanf("%d",&n) != eof){

if(n== 0) break;

memset(map,inf, sizeof(map));

for(inti = 0; i < n*(n-1)/2; i ++){

scanf("%d%d%d%d",&a, &b, &dis, &t);

addedge(a-1,b-1, dis, t);

prime();

printf("%d\n",ans);

return0;

繼續暢通工程 hdu 1879

include 2243673 2010 03 24 20 56 41 accepted 1879 375ms 320k 1070 b c 悔惜晟 include 修改了三次終於ac,為何就是 的效率不高 include include using namespace std int s 4991 ...

hdu 1879 繼續暢通工程

include include include typedef structedge edge input 5050 int cost 5050 int parent 5050 int cmp const void a,const void b int root int n int kruskal ...

HDU 1879 繼續暢通工程

和前幾個最小生成樹有點不一樣的地方就是 在kruskal裡面,要先把已經修通的路排在前面 不知道這樣是不是多此一舉呢 再按照每條路的價值從小到大排序 自定義排序規則就是 呼叫c 的sort int cmp const e a,const e b 將每條邊存在結構體edge裡面 struct e ed...