BJ模拟 Cut (最小割树+最小生成树)

来源:互联网 发布:mac格式化u盘 编辑:程序博客网 时间:2024/05/17 06:47

Description

Sample Input

30 2 2 2 0 22 2 0

Sample Output

22 3 21 3 2

题解:

即将完全图连边 跑一遍最大生成树(只需修改最小生成树判断条件)

每次连边都连向之前的联通块且该边为当前最小 所以答案正确

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>using namespace std;typedef long long ll;const int Maxn= 1000;int f[Maxn][Maxn];inline int read(){    char ch=getchar();int i=0,f=1;    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){i=(i<<3)+(i<<1)+ch-'0';ch=getchar();}    return i*f;}struct node{    int to;    int val;    node(int x,int val):to(x),val(val){}    friend inline bool operator <(const node &a,const node &b) {        return a.val<b.val;    }};vector<node>edge[Maxn];vector<node>edge2[Maxn];priority_queue<node>q;int dis[Maxn],match[Maxn];ll dis2[Maxn];int n;bool vis[Maxn];void display(const vector<node>& vec) {for (auto i: vec) {cout << i.to << ' ' << i.val << endl;}cout << endl;}inline void Insert(int x,int y,int z){    edge[x].push_back(node(y,z));    edge[y].push_back(node(x,z));}inline void InsertEdge2(int x,int y,int z){edge2[x].push_back(node(y,z));edge2[y].push_back(node(x,z));}inline void Prim(){    dis[1]=0;    q.push(node(1, 0));    for(int i = 1; i <= n; i++)    {        while(!q.empty() && vis[q.top().to]) q.pop();        node tmp = q.top();        q.pop();        int now = tmp.to;        vis[now] = 1;        int siz = edge[now].size();        for(int v,e = 0; e < siz; e++) {            v = edge[now][e].to;            int va = edge[now][e].val;            if (!vis[v])            {                if(dis[v] < va)                {                    dis[v] = va;                    match[v] = now;                    q.push(node(v, va));                }            }        }    }}inline bool judge(){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(f[i][j]!=f[j][i])return true;return false;}inline void Dfs(int now,int f){int siz=edge2[now].size();for(int v,e=0;e<siz;e++){v=edge2[now][e].to;if(v!=f){dis2[v]=min(dis2[now], (ll)edge2[now][e].val);Dfs(v,now);}}}inline bool judgevaild(){for(int i=1;i<=n;i++) {if(match[i]) InsertEdge2(i,match[i],dis[i]);}for(int i=1;i<=n;i++) {memset(dis2,0x3f,sizeof(dis2)); Dfs(i,0);dis2[i]=0;for(int j=1;j<=n;j++){if(j==i)continue;if(dis2[j] != f[i][j])return true;}}return false;}int main(){    n=read();    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        {            f[i][j]=read();            if(i!=j) Insert(i, j, f[i][j]);        }    if(judge()) cout<<-1;    else    {    Prim();    if(judgevaild())cout<<-1;    else    {    cout<<n-1<<endl;    for(int i=1;i<=n;i++)    {        if(match[i])        printf("%d %d %d\n",i,match[i],dis[i]);    }}}return 0;}


1 0