题目描述
输入
输出
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
8 7
3 4
1 2
2 3
3 1
3 6
4 5
7 8
1 1
0 0
0 0
0 1
1 0
1 0
1 0
0 1
样例输出
3
0
0
0
2
2
1
提示
迎接FFF团的胜利!
第二题也许算是很简单的了。人家图的边名字都取成桥了你怎么能不做成桥呢……是吧……
对于一条边,如果不是桥(即炸毁它不会发生图的断裂),则它的答案为0(显然)。否则呢~则为分开的两部分男女数量互相乘再加起来(如两部分男女数量:land1-boy10 girl9 land2-boy7 girl8,可以摧毁10*8+9*7=143对情侣),这可以用一个简单的size数组来解决。
那么求出桥的方法就是tarjan的时间戳了……没有什么讲的必要……
PS:尽管题目口口声声说没有重边,数据也一改再改,但它就是有重边=_=|||……然而标称却没有判重……尬……导致我判了重的代码WA了……O__O"
代码:
1.这是不判重的(判断可走不可走只看是否是父亲)
//%>_<% ~(>_<)~
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
#define M 1000005
#define ll long long
int n,m;
ll boy[N],girl[N];
int fir[N],t[M],nex[M],cnt=1;
int tim,dfn[N],low[N];
bool root[N],bdg[M],vis[N];
ll FFF[M];
void add(int a,int b)
{
cnt++;
t[cnt]=b;
nex[cnt]=fir[a];
fir[a]=cnt;
}
void dfs(int r,int fa)
{
dfn[r]=low[r]=++tim;
for(int i=fir[r];i;i=nex[i])
{
int v=t[i];
if(v!=fa)
{
if(dfn[v])
low[r]=min(low[r],dfn[v]);
else
{
dfs(v,r);
boy[r]+=boy[v];
girl[r]+=girl[v];
if(low[v]>dfn[r])
bdg[i]=bdg[i^1]=1;
else
low[r]=min(low[r],low[v]);
}
}
}
}
int allboy,allgirl;
void dfs2(int r)
{
vis[r]=1;
for(int i=fir[r];i;i=nex[i])
{
int v=t[i];
if(!vis[v])
{
if(bdg[i])
FFF[i]=FFF[i^1]=(allboy-boy[v])*girl[v]+(allgirl-girl[v])*boy[v];
dfs2(v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1;i<=n;i++)
scanf("%lld%lld",&boy[i],&girl[i]);
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
root[i]=1;
dfs(i,0);
}
}
for(int i=1;i<=n;i++)
if(root[i])
allboy=boy[i],allgirl=girl[i],dfs2(i);
for(int i=1;i<=m;i++)
printf("%lld\n",FFF[2*i]);
}
2.然后这是判了重的(判断能不能走到不再判断是否是父亲,而是判断是否是来时的边的反向边)
//%>_<% ~(>_<)~
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
#define M 1000005
#define ll long long
int n,m;
ll boy[N],girl[N];
int fir[N],t[M],nex[M],cnt=1;
int tim,dfn[N],low[N];
bool root[N],bdg[M],vis[N];
ll FFF[M];
void add(int a,int b)
{
cnt++;
t[cnt]=b;
nex[cnt]=fir[a];
fir[a]=cnt;
}
void dfs(int r,int fr)
{
dfn[r]=low[r]=++tim;
for(int i=fir[r];i;i=nex[i])
{
int v=t[i];
if((i^1)!=fr)
{
if(dfn[v])
low[r]=min(low[r],dfn[v]);
else
{
dfs(v,i);
boy[r]+=boy[v];
girl[r]+=girl[v];
if(low[v]>dfn[r])
bdg[i]=bdg[i^1]=1;
else
low[r]=min(low[r],low[v]);
}
}
}
}
int allboy,allgirl;
void dfs2(int r)
{
vis[r]=1;
for(int i=fir[r];i;i=nex[i])
{
int v=t[i];
if(!vis[v])
{
if(bdg[i])
FFF[i]=FFF[i^1]=(allboy-boy[v])*girl[v]+(allgirl-girl[v])*boy[v];
dfs2(v);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1;i<=n;i++)
scanf("%lld%lld",&boy[i],&girl[i]);
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
root[i]=1;
dfs(i,0);
}
}
for(int i=1;i<=n;i++)
if(root[i])
allboy=boy[i],allgirl=girl[i],dfs2(i);
for(int i=1;i<=m;i++)
printf("%lld\n",FFF[2*i]);
}