链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2305
题解
首先,交换任何一直左鞋子和右鞋子都是没有意义的
也就是说,左鞋子只能和左鞋子交换,右鞋子只能和右鞋子交换,那其实就等价于我只交换右鞋子,或者只交换左鞋子
那么对于输入的数对
(
a
,
b
)
(a,b)
(a,b),我在图中连边
a
→
b
a\rightarrow b
a→b,这就表示了
b
b
b所在的位置需要一个
a
a
a这样的鞋子,每个点的出度为
1
1
1且入度为
1
1
1,显然这是一个置换,这张图由若干个环组成。
对于一个大小为
m
m
m的环,我需要
m
−
1
m-1
m−1次交换去让它变成
m
m
m个自环
因此这题的答案就是
n
−
n-
n−环数
代码
#include <bits/stdc++.h>
#define maxn 10010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
ll n, f[maxn], vis[maxn], a[maxn], b[maxn];
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
int main()
{
ll T=read(), i, ans, cnt, p;
while(T--)
{
n=read();
for(i=1;i<=n;i++)
{
a[i]=read(), b[i]=read();
f[a[i]]=b[i];
vis[a[i]]=0;
}
ans=n;
for(i=1;i<=n;i++)
if(!vis[a[i]])
{
ans--;
for(p=a[i];!vis[p];p=f[p])vis[p]=true;
}
printf("%lld\n",ans);
}
return 0;
}