算次小生成树模板吧,prim的话。。。应该就是更新MAX数组的时候,不是直接=,语句是MAX[u][v] = MAX[v][u] = max(MAX[pre[u]][v], dis[u]);//dis[u] = MAX[u][pre[u]]
//心累....第一次拿map做标记,然后,,就遇到问题了,,,拿样例二就会发现,计入map的大小不对....然后,就会发现,由于first是Edge,有三个数,然后,重载的<只有dist,当dist相同时,,他不会计入,样例二刚好就是4个dist都为2....所以a.size会为1,,所以 在重载<的时候,需要==考虑进去........(ps:刚开始还以为是a.clear的问题...改成erase也不对,改成局部成员也不对...)
然后,用这个套秦始皇那道题的时候,,会发现,,,MAX少了一部分,是因为更新vector只加入了一部分,另一部分未加入,但是...另一部分也加入的时候在这道题里会出现MLE问题...找到的问题是G的更新用的是原本的u, v节点,实际上应该用的是u,v的根结点。。。改了就AC了...然后 改了也发现,实际上真的只用更新一次G就可以了,MAX也全了....所以,,归根结底,我更新G的时候应该用u,v的根结点...............
AC全面部分
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
const int N = 1000+5;
const int INF = 0x3f3f3f3f;
struct Edge{
int u, v, dist;
Edge(){
u = 0;
v = 0;
dist = 0;
};
Edge(int a, int b, int c){
u = a;
v = b;
dist = c;
}
}edge;
vector<int> G[N];
bool operator <(Edge a, Edge b)
{
if(a.dist == b.dist){//加这个,是因为我用了map来标记,,然后,,first是edge,当dist相等时,,他不加入,,所以,这个语句就是为了标记而用
if(a.u == b.u)
return a.v > b.v;
return a.u > b.u;
}
return a.dist > b.dist;
}
ostream & operator<< (ostream & os, const Edge& A){
os << A.u << "--" << A.v << "=" << A.dist << endl;
}
priority_queue<Edge> q;
int judge[N][N] = {0};
int MAX[N][N];
int pre[N*N/2] = {0};
void init(int n)
{
memset(MAX, 0, sizeof(MAX));
// a.clear();
// cout << a.size() << endl;
// a.erase(a.begin(), a.end());
for(int i=0; i<=n; i++){
pre[i] = i;
G[i].clear();
G[i].push_back(i);
}
}
int Find(int a)
{
return pre[a] == a ? a : pre[a] = Find(pre[a]);
}
void Union(int a, int b)
{
if(a == b){
return;
}
else{
pre[a] = b;
return;
}
}
void Kruskal(map<Edge, int> ta)
{
int sum = 0, u, v;
while(!q.empty()){
edge = q.top();
q.pop();
u = Find(edge.u), v = Find(edge.v);
if(u != v){
sum += edge.dist;
ta[edge] = 1;//标记
Union(u, v);
for(int i=0; i<G[u].size(); i++){
for(int j=0; j<G[v].size(); j++){
MAX[G[u][i]][G[v][j]] = MAX[G[v][j]][G[u][i]] = edge.dist;//边是从小到大排序的,直接等于目前最长的边即可
}
}
for(int i=0; i<G[u].size(); i++){//因为u为v的子树
G[v].push_back(G[u][i]);
}
}
}
//cout << sum << endl;
int Ssum = INF;
map<Edge, int>::iterator it;
for(it=ta.begin(); it!=ta.end(); it++) {
// cout << it->first << endl;
if(it->second == 0){//未被标记
int dist=it->first.dist, u=it->first.u, v=it->first.v;
// cout << dist << ":" << MAX[u][v] << endl;
Ssum = min(Ssum, sum+dist-MAX[u][v]);
}
}
// cout << sum << " " << Ssum << endl;
if(Ssum > sum) cout << sum << endl;
else cout << "Not Unique!" << endl;
}
int main()
{
int T;
cin >> T;
while(T--){
map<Edge, int> a;
int n, m;
cin >> n >> m;
while (!q.empty()) {
q.pop();
}
init(n);
for (int i = 1; i <= m; i++) {
cin >> edge.u >> edge.v >> edge.dist;
a[edge] = 0;
q.push(edge);
}
// cout << a.size() << endl;
Kruskal(a);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const LL N = 100+5;
int n, m;
struct Edge {
int u, v, w;
}edge[N * N];
int pre[N], rak[N];
int MAX[N][N];
bool vis[N*N];
vector<int> G[N]; //存储MST
void init(int n) {
memset(vis, 0, sizeof(vis));
for(int i = 0; i <= n; i++)
pre[i] = i, rak[i] = 0, G[i].clear(), G[i].push_back(i);
}
int Find(int x) {
return (x == pre[x])? x : pre[x] = Find(pre[x]);
}
bool Union(int x, int y)
{
if(x != y){
pre[x] = y;
return true;
}
return false;
}
bool cmp(const Edge &a, const Edge &b)
{
return a.w < b.w;
}
void Kruskal() {
sort(edge+1, edge+1+m, cmp);
init(N);
int sum = 0;
for(int i=1; i<=m; i++) {
int u = Find(edge[i].u), v = Find(edge[i].v), w = edge[i].w;
if(Union(u, v)) {
sum += w, vis[i] = true;
for(int j = 0; j < G[u].size(); ++j)//此处的u,v均为根结点
for(int k = 0; k < G[v].size(); ++k)
MAX[G[u][j]][G[v][k]] = MAX[G[v][k]][G[u][j]] = w;
for(int j = 0; j < G[u].size(); ++j)
G[v].push_back(G[u][j]);
}
}
int Ssum = inf;
for(int i=1; i<=m; ++i)
if(!vis[i])
Ssum = min(Ssum, sum+edge[i].w-MAX[edge[i].u][edge[i].v]);
if(Ssum > sum) cout << sum << endl;
else cout << "Not Unique!" << endl;
// cout << sum << " " << Ssum << endl;
}
int main() {
int T;
cin >> T;
while(T--){
cin >> n >> m;
for(int i=1; i<=m; ++i)
cin >> edge[i].u >> edge[i].v >> edge[i].w;
Kruskal();
}
return 0;
}
//*************************蒙对部分.....不严谨..........................
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
const int N = 1000+5;
const int INF = 0x3f3f3f3f;
struct Edge{
int u, v, dist;
Edge(){
u = 0;
v = 0;
dist = 0;
};
Edge(int a, int b, int c){
u = a;
v = b;
dist = c;
}
}edge;
vector<int> G[N];
bool operator <(Edge a, Edge b)
{
if(a.dist == b.dist){//加这个,是因为我用了map来标记,,然后,,first是edge,当dist相等时,,他不加入,,所以,这个语句就是为了标记而用
return a.u > b.u;
}
return a.dist > b.dist;
}
ostream & operator<< (ostream & os, const Edge& A){
os << A.u << "--" << A.v << "=" << A.dist << endl;
}
priority_queue<Edge> q;
int judge[N][N] = {0};
int MAX[N][N];
int pre[N*N/2] = {0};
void init(int n)
{
// memset(judge, 0, sizeof(judge));
// a.clear();
// cout << a.size() << endl;
// a.erase(a.begin(), a.end());
for(int i=0; i<=n; i++){
pre[i] = i;
G[i].clear();
G[i].push_back(i);
}
}
int Find(int a)
{
return pre[a] == a ? a : pre[a] = Find(pre[a]);
}
void Union(int a, int b)
{
a = Find(a), b = Find(b);
if(a == b){
return;
}
else{
pre[a] = b;
return;
}
}
void Kruskal(map<Edge, int> ta)
{
int sum = 0, u, v;
while(!q.empty()){
edge = q.top();
q.pop();
u = edge.u, v = edge.v;
if(Find(u) != Find(v)){
sum += edge.dist;
ta[edge] = 1;//标记
Union(u, v);
for(int i=0; i<G[u].size(); i++){
for(int j=0; j<G[v].size(); j++){
MAX[G[u][i]][G[v][j]] = MAX[G[v][j]][G[u][i]] = edge.dist;//边是从小到大排序的,直接等于目前最长的边即可
}
}
//两个都必须要,不然MAX可能会不全,但是会存在MLE问题...
for(int i=0; i<G[u].size(); i++){//因为u为v的子树
G[v].push_back(G[u][i]);
}
/*
for(int i=0; i<G[v].size(); i++){//因为u为v的子树
G[u].push_back(G[v][i]);
}*/
}
}
//cout << sum << endl;
int Ssum = INF;
map<Edge, int>::iterator it;
for(it=ta.begin(); it!=ta.end(); it++) {
// cout << it->first << endl;
if(it->second == 0){//未被标记
int dist=it->first.dist, u=it->first.u, v=it->first.v;
// cout << dist << ":" << MAX[u][v] << endl;
Ssum = min(Ssum, sum+dist-MAX[u][v]);
}
}
// cout << sum << ":" << Ssum << endl;
if(Ssum > sum) cout << sum << endl;
else cout << "Not Unique!" << endl;
}
int main()
{
int T;
cin >> T;
while(T--){
map<Edge, int> a;
int n, m;
cin >> n >> m;
while (!q.empty()) {
q.pop();
}
init(n);
for (int i = 1; i <= m; i++) {
cin >> edge.u >> edge.v >> edge.dist;
a[edge] = 0;
q.push(edge);
}
// cout << a.size() << endl;
Kruskal(a);
}
return 0;
}