2014年3月29日 星期六

spanning tree Kruskal C++

example input :
====================================                  
a-b 2
b-c 4
c-f 5
e-f 5
d-e 2
d-a 4
d-b 4
b-e 3
b-f 1
exit
===================================
#include <iostream>
#include<string>
#include<vector>
using namespace std;
struct link{
string node1;
string node2;
int weighted;
};
void split(string,vector<link>*);
void sort(vector<link>*);
int count_node(vector<link>*, vector<string>*);
int main()
{
vector<link>input;                      //原始input
vector<string>n_list; //node的list
vector<link>answer;                     //最後要輸出的結果
string command;                         //每一行輸入
int size,edge_count=0,node_count;
while (true)
{
getline(cin, command);
if (command == "exit")
break;
split(command, &input);
}
sort(&input);                            //根據權重由小到大排

node_count = count_node(&input,&n_list);                    //算有幾個點 & 做出點的list
int *Visited = new int[node_count]; //建立node set概念用
for (int i = 0; i < node_count; i++)
Visited[i] = 0;
link tmp;
int node1_pos,node2_pos,total_weighted=0;
int min,bigger;
for (int i = 0;edge_count != node_count-1 ; i++) //找出答案
{
tmp = input[i];
for (int j = 0; j < node_count; j++)
{
if (tmp.node1 == n_list[j])
{
node1_pos = j;
break;
}
}
for (int j = 0; j < node_count; j++)
{
if (tmp.node2 == n_list[j])
{
node2_pos = j;
break;
}
}
if ((Visited[node1_pos] == 0) && (Visited[node2_pos] == 0))
{
Visited[node1_pos] = i+1;
Visited[node2_pos] = i+1;
answer.push_back(tmp);
edge_count++;
total_weighted = total_weighted + tmp.weighted;
}
else if (Visited[node1_pos] == 0 || Visited[node2_pos]==0)
{
if (Visited[node1_pos] == 0)
Visited[node1_pos] = Visited[node2_pos];
else
Visited[node2_pos] = Visited[node1_pos];
answer.push_back(tmp);
edge_count++;
total_weighted = total_weighted + tmp.weighted;
}
else if (Visited[node1_pos] != 0 && Visited[node2_pos] != 0 && Visited[node1_pos] != Visited[node2_pos])
{
if (Visited[node1_pos] > Visited[node2_pos])
{
min = Visited[node2_pos];
bigger = Visited[node1_pos];
}
else
{
min = Visited[node1_pos];
bigger = Visited[node2_pos];
}
for (int k = 0; k < node_count; k++)
{
if (Visited[k] == bigger)
Visited[k] = min;
}
answer.push_back(tmp);
edge_count++;
total_weighted = total_weighted + tmp.weighted;
}
else
;
}
size = answer.size(); //印答案
for (int i = 0; i < size; i++)
cout << answer[i].node1 << "-" << answer[i].node2 << "  " << answer[i].weighted << endl;
cout << "total weighted = " << total_weighted << endl;
return 0;
}
void split(string input, vector<link>* data)
{
int dash_pos, space_pos;
int str_len = input.length();
link push_back;
string tmp = "";
for (int i = 0; i < str_len; i++) //找 - 位置
{
if (input[i]=='-')
{
dash_pos = i;
break;
}
}
for (int i = dash_pos + 1; i < str_len; i++)//找 空白 位置
{
if (input[i] == ' ')
{
space_pos = i;
break;
}
}
for (int j = 0; j < dash_pos; j++)
tmp = tmp + input[j];
push_back.node1 = tmp;
tmp = "";
for (int j = dash_pos + 1; j < space_pos; j++)
tmp = tmp + input[j];
push_back.node2 = tmp;
tmp = "";
for (int j = space_pos + 1; j < str_len; j++)
tmp = tmp + input[j];
push_back.weighted = atoi(tmp.c_str());
data->push_back(push_back);
}
void sort(vector<link>* data)
{
int size = data->size();
link tmp;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size - 1; j++)
{
if ((*data)[j].weighted >(*data)[j+1].weighted)
{
tmp = (*data)[j];
(*data)[j] = (*data)[j + 1];
(*data)[j + 1] = tmp;
}
}
}
}
int count_node(vector<link>* data, vector<string>* node_set) //算點數 同時做出點的list
{
int count = 0;
int size = data->size();
int len;
for (int i = 0; i < size; i++)
{
link tmp = (*data)[i];
string node1 = tmp.node1;
string node2 = tmp.node2;
bool node1_flag = 0, node2_flag = 0;
len = node_set->size();
for (int j = 0; j < len; j++)
{
if (node1 == (*node_set)[j])
{
node1_flag = 1;
break;
}
}
if (node1_flag == 0)
{
(*node_set).push_back(node1);
count++;
}
len = (*node_set).size();
for (int k = 0; k < len; k++)
{
if (node2 == (*node_set)[k])
{
node2_flag = 1;
break;
}
}
if (node2_flag == 0)
{
(*node_set).push_back(node2);
count++;
}
}
return count;
}

沒有留言:

張貼留言