HDU - 5452 Minimum Cut
直达车:HDU - 5459
题目解读:
给出一颗n个节点的生成树的n-1条边的端点,再给出几条非树边,问删掉最少的边使图不联通,最少几条。
题目样例弱,导致可以乱写水过。。。。
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N =8e4+7;
int dp[2*N][26];
bool vis[26];
int n, m;
struct edge
{
int from, to;
int next;
} e[2*N];
edge note[N*2];
int head[N],head2[N];
int cnt,cnt2;
int num[N];
int p[N];
void init()
{
memset(head2,-1,sizeof(int)*(n*2));
memset(head,-1,sizeof(int)*(n*2));
for(int i=0;i<=n*2;i++) vis[i]=0;
for(int i=0;i<=n;i++) p[i] = i;
cnt = 0;
cnt2=0;
}
void addedge(int u, int v)
{
e[cnt].from = u;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void addedge2(int u, int v)
{
note[cnt2].from = u;
note[cnt2].to = v;
note[cnt2].next = head2[u];
head2[u] = cnt2++;
}
int DFS(int u,int fa)
{
for(int i = head[u]; ~i; i = e[i].next)
{
int v = e[i].to;
if(v == fa)
continue;
DFS(v, u);
num[u]+=num[v];
}
return 0;
}
int finds(int x){return p[x]==x?x:p[x]=finds(p[x]);}
int father[2*N];
void Tarjan(int s)
{
vis[s] = 1;
int next = head2[s];
while(next!=-1)
{
if(vis[note[next].to])
{
father[next] = finds(p[note[next].to]);
father[next^1]=father[next];
}
next = note[next].next;
}
next = head[s];
while(next!=-1)
{
if(!vis[e[next].to])
{
Tarjan(e[next].to);
p[e[next].to] = s;
}
next = e[next].next;
}
}
int main()
{
freopen("in.txt","r",stdin);
int t;
int cas = 0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
int u, v;
for(int i = 0; i < n-1; i++)
{
scanf("%d%d",&u,&v);
addedge(u, v);
addedge(v, u);
}
// for(int i=0;i<=m-n;i++)
// {
// scanf("%d%d",&u,&v);
// addedge2(u, v);
// addedge2(v, u);
// }
//Tarjan(1);
for(int i = 0; i <= m-n; i++)
{
int tt = 0;
num[u]++;
num[v]++;
num[tt]-=2;
}
DFS(1, 1);
int ans = INF;
for(int i = 2; i <= n; i++)
{
ans = min(ans, num[i]+1);
}
printf("Case #%d: %d\n",++cas,ans);
}
return 0;
}