给定一张 n≤3000 的完全无向图,已知边权,求一定在MST上的边的边数
先求出MST,
然后令
f[roo][i]
表示以roo为根,是否存在一条非树边
(roo,v)
其与树链
(roo,x)
构成环
(roo→x→v→roo)
然后对于一条边 (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;
}