|
发表于 2022-1-30 20:55:14
|
显示全部楼层
本帖最后由 guosl 于 2022-1-30 20:56 编辑
本题是一个典型的最小生成树。我应用了Kruskal算法。
为了读取数据方便我把数据文件中的”-“改成了100000,而把”,“改成了空格。
- /*
- 答案:259679
- */
- #include <cstdio>
- #include <vector>
- #include <algorithm>
- using namespace std;
- const int N = 40;
- const int INF = 100000;
- struct stEdge
- {
- int p1, p2;
- int nLen;
- bool operator<(const stEdge& e) const
- {
- return (nLen < e.nLen);
- }
- };
- vector<stEdge> v;
- int r[N];
- int findroot(int nId)
- {
- if (r[nId] == nId)
- return nId;
- r[nId] = findroot(r[nId]);
- return r[nId];
- }
- bool mg(int nId1, int nId2)
- {
- int rd1 = findroot(nId1);
- int rd2 = findroot(nId2);
- if (rd1 == rd2)
- return false;
- if (rd1 < rd2)
- r[rd2] = rd1;
- else
- r[rd1] = rd2;
- return true;
- }
- int main(void)
- {
- long long nTotalLen = 0;
- for (int i = 0; i < N; ++i)
- r[i] = i;
- //读入数据
- errno_t err;
- FILE* fp = NULL;
- err = fopen_s(&fp,"p107_network.txt", "r");//打开文件
- if (err != 0)
- {
- printf_s("数据文件未打开\n");
- return 0;
- }
- for (int i = 0; i < N; ++i)
- {
- for (int j = 0; j < N; ++j)
- {
- int x = 0;
- fscanf_s(fp, "%d", &x);
- if (j > i && x != INF)
- {
- stEdge e;
- e.p1 = i;
- e.p2 = j;
- e.nLen = x;
- v.push_back(e);
- nTotalLen += x;
- }
- }
- }
- fclose(fp);
- sort(v.begin(), v.end());
- int nMinSum = 0;
- for (int i = 0; i < (int)v.size(); ++i)
- {
- if (mg(v[i].p1, v[i].p2))
- nMinSum += v[i].nLen;
- }
- printf_s("%d\n", nTotalLen - nMinSum);
- return 0;
- }
复制代码 |
|