1. 程式人生 > >1679 The Unique MST 次小生成樹

1679 The Unique MST 次小生成樹

題目連結

題意:給定一個n個頂點的圖,求問該圖的最小生成樹是否為唯一解,若是唯一解則輸出答案,不是則輸出“Not Unique!”。

思路:次小生成樹模板題,和最小生成樹的值比較一下就行了。

次小生成樹:先求出某個最小生成樹,然後n^{2}跑一遍求該樹上任意兩個點的路徑上權值最大的邊maxedge[i,j],然後通過列舉圖上邊edge<i,j>,若不是樹上的邊,則用edge<i,j>替換maxedge[i,j]。這樣就求出一個比最小生成樹大的生成樹,其中最小的生成樹就是次小生成樹了。

#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<deque>
#define ll long long
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 1000005
#define N 10005
#define debug true
#define lowbit(x) ((-x)&x)
#define ffor(i, d, u) for (int i = (d); i <= (u); ++i)
#define _ffor(i, u, d) for (int i = (u); i >= (d); --i)
#define mst(array, Num, Kind, Count) memset(array, Num, sizeof(Kind) * (Count))
using std::max;
using std::queue;
const int P = 1e9 + 7;
int n, m;
bool pick[NUM], root[105];
int maxedge[105][105];
struct node
{
    int l, id;
} ma[105][105];
struct node1
{
    int l, f;
} dist[105];
template <typename T>
void read(T& x)
{
    x = 0;
    char c;T t = 1;
    while(((c=getchar())<'0'||c>'9')&&c!='-');
    if(c=='-')t = -1,c = getchar();
    do(x*=10)+=(c-'0');while ((c = getchar()) >= '0' && c <= '9');
    x *= t;
}
template <typename T>
void write(T x)
{
    int len = 0;char c[21];
    if(x<0)putchar('-'), x *= (-1);
    do{++len;c[len]=(x%10)+'0';}while (x /= 10);
    _ffor(i, len, 1) putchar(c[i]);
}
void bfs(const int &st)//求樹上點對路徑上邊的最小權值
{
    queue<int> q;
    int x;
    bool check[105] = {};
    maxedge[st][st] = 0;
    x = st;
    check[st] = true;
    q.push(x);
    while(!q.empty())
    {
        x = q.front(), q.pop();
        ffor(i,1,n)
        {
            if(check[i]||ma[x][i].l==INF||!pick[ma[x][i].id>>1])
                continue;
            maxedge[i][st] = maxedge[st][i] = max(maxedge[st][x], ma[x][i].l);
            check[i] = true;
            q.push(i);
        }
    }
}
void AC()
{
    int t, x, y, pp, minx, ans;
    bool flag;
    read(t);
    dist[0].l = INF;
    while(t--)
    {
        read(n), read(m);
        mst(root, false, bool, n + 1), mst(pick, false, bool, m + 1);
        ffor(i, 1, n) ffor(j, 1, n) ma[i][j].l = ma[j][i].l = INF;
        ffor(i,1,m)
        {
            read(x), read(y);
            read(ma[x][y].l), ma[y][x].l = ma[x][y].l;
            ma[y][x].id = (ma[x][y].id = (i << 1) - 1) - 1;
        }
        flag = false,pp = 1,ans = 0,root[1] = true;
        ffor(i, 2, n) dist[i].l = ma[1][i].l, dist[i].f = 1;
        ffor(i,2,n)//prim
        {
            minx = 0;
            ffor(j,2,n)
            {
                if(root[j])
                    continue;
                if(dist[minx].l > dist[j].l)
                    minx = j;
            }
            root[minx] = pick[ma[dist[minx].f][minx].id >> 1] = true, ans += dist[minx].l;
            ffor(j,2,n)
            {
                if(root[j])
                    continue;
                if(dist[j].l > ma[minx][j].l)
                {
                    dist[j].l = ma[minx][j].l;
                    dist[j].f = minx;
                }
            }
        }
        ffor(i, 1, n) bfs(i);
        ffor(i,1,n)
        {
            ffor(j,i+1,n)
            {
                if(pick[ma[i][j].id>>1])
                    continue;
                if(ma[i][j].l==maxedge[i][j])
                {
                    flag = true;
                    break;
                }
            }
            if(flag)
                break;
        }
        if(flag)
            puts("Not Unique!");
        else
        {
            write(ans);
            putchar('\n');
        }
        
    }
}
int main()
{
    AC();
    return 0;
}