HDU 5483(Nux Walpurgis-一定在MST中的边)

来源:互联网 发布:mssql数据库管理工具 编辑:程序博客网 时间:2024/05/18 00:52

给定一张n3000  的完全无向图,已知边权,求一定在MST上的边的边数

先求出MST,
然后令f[roo][i]  表示以roo为根,是否存在一条非树边(roo,v) 其与树链
(roo,x) 构成环(rooxvroo) 

然后对于一条边(x,v) ,然后让v的子树作根,连接到x以下的节点去。

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define pb push_back#define mp make_pair #define MAXW (3000+10)#define MAXN (3000+10)#define MAXT (20+10)#define MAXM (6000+10)typedef long long ll;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int n,Map[MAXN][MAXN]={0};int edge[MAXM],Next[MAXM],Pre[MAXM],siz=1;void addedge(int u,int v) {    edge[++siz]=v;    Next[siz]=Pre[u];    Pre[u]=siz;}void addedge2(int u,int v) {addedge(u,v),addedge(v,u);} int dis[MAXN],vis[MAXN],pree[MAXN];int prim(){       int mst=0;    MEM(Pre) siz=1;    MEM(vis)    dis[1]=0; vis[1]=1;     Fork(i,2,n)    {         dis[i]=Map[1][i];         pree[i]=1;    }    dis[0]=INF;    For(j,n-1) {        int k=0;        For(i,n) if (!vis[i] && dis[k] > dis[i] ) k = i;        addedge2(pree[k],k);        mst+=dis[k];        vis[k]=1; dis[k]=0;        For(i,n) {            if (!vis[i] && dis[i] > Map[k][i] ) {                dis[i]=Map[k][i]; pree[i]=k;            }         }    }    return mst;} int f[MAXN][MAXN],roo;void dfs(int x,int fa){    if ( x == roo || fa == roo ) f[roo][x] = INF;     else f[roo][x]=Map[roo][x];    Forp(x) {        int v=edge[p];        if (fa==v) continue;        dfs(v,x);         f[roo][x]=min(f[roo][x],f[roo][v]);    }}int dfs2(int x,int fa,int y) {    int ans=f[x][y];    Forp(x) {        int v=edge[p];        if (fa==v) continue;        ans=min(ans,dfs2(v,x,y));     }    return ans;}void calc() {    int ans=n-1;    For(x,n) {        Forp(x)         {            int v=edge[p];            if (x>=v) continue;            if (dfs2(x,v,v)==Map[x][v])             {                ans--;            }        }    }    cout<<ans<<endl;}int main(){//  freopen("hdu5483.in","r",stdin);//  freopen(".out","w",stdout);    int T;cin>>T;    while (T--) {        cin>>n;        For(i,n-1)        {            Fork(j,i+1,n) {                scanf("%d",&Map[i][j]);                Map[j][i]=Map[i][j];            }        }           int mst=prim();        For(i,n) f[i][i]=0;        For(i,n) roo=i,dfs(i,0);         calc();    }    return 0;}
0 0
原创粉丝点击