hust/ural Penguin-Avia 最小生成树
题型:无向图,删边加边有代价,问最小生成树同时代价最小
题意:
处理:DFS找连通分支(无向图,一定是强连通分支),删去环边,再将再连通分支树的根节点连接。
bug ; 在go的意义上混淆过,分析如下
数据结构:
const int add_e = 2; const int delete_e = 3; const int ok_e = 4; int n,d,a; long long cost; int m[110][110],go[110]; // m是输入的图(值为0/1),处理后值为234(对应0ad) // go[i]表示第i个节点所在的分支。
删边操作:
void DFS(int u,int c){ for(int v=0;v<n;++v){ if(m[u][v]==1){ //print(); if(go[v]==0){ // 形成环 //cout << "u v : " << u << " " << v << endl; //print() , output matrix m go[v]=c; m[u][v]=m[v][u]= ok_e; DFS(v,c); } else{ // cout << u << " "<< v <<endl;print(); cost += d; m[u][v]=m[v][u]= delete_e; } } } }
将所有的连通树连接起来:
// find add edge,connect non-connect compont
// block[i] is 是第i个节点所在分支编号,block全部为true表示所有节点连通 vector<bool> block(comp+1,false); block[go[0]]=true; for( int i=1;i<n;++i){ if(go[i]!=go[0] && block[go[i]]==false ){ m[i][0]=m[0][i]=add_e; cost += a; block[go[i]] = true; } }
完整代码 : https://github.com/Iytz/algorithm/blob/master/graph/Penguin-Avia_1H.cpp