您的位置:首页 > 其它

图论——连通图

2015-09-24 14:05 176 查看
Tyvj 2059 元芳看电影

描述

神探狄仁杰电影版首映这天,狄仁杰、李元芳和狄如燕去看电影。由于人实在是太多了,入场的队伍变得十分不整齐,一个人的前面可能会出现并排的好多人。
“元芳,这队伍你怎么看?”
“大人,卑职看不出这队伍是怎么排的!但是卑职看出了一些两个人之间的前后关系!”
“那么我们可以写个程序计算出来一定没有和其它人并排的人数。”
“大人/叔父真乃神人也!”

输入格式

第一行两个数N、M,表示队伍一共有N个人,元芳看出了M对关系。
接下来M行每行两个数a、b,表示a在b的前面(不一定正好在b的前面,ab之间可能有其他人)。

输出格式

有多少个人一定没有和其他人并排。

测试样例1

输入

3 2
1 2
1 3

输出

1


备注

对于100%的数据,1<=N<=100,0<=M<=4500。数据保证M对关系不出现矛盾。sjynoi

思路:
floyd传递闭包,如果所有人除了自己都在都在自己的前或后,就一定不并排

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>

using namespace std;

const int maxn = 1000;
char temp[maxn];
int edge[maxn][maxn],cou[maxn],n,k,big[maxn];

void init(){
cin>>temp>>k;
n = strlen(temp);
for(int i = 0;i <= 9;i++){
for(int j = 0;j <= 9;j++){
if(i == j) edge[i][j] = 1;
else edge[i][j] = 0;
}
}
for(int i = 0;i < k;i++){
int u,v;
cin>>u>>v;
edge[u][v] = 1;
}
big[0] = 1;

}

void fshort(){
for(int k = 0;k <= 9;k++){
for(int i = 0;i <= 9;i++){
if(i != k){
for(int j = 0;j <=9;j++)
if(j != i && j != k &&(edge[i][k] && edge[k][j])) edge[i][j] = 1;

}
}
}
for(int i = 0;i <= 9;i++)
for(int j = 0;j <= 9;j++)
cou[i] += edge[i][j];

}

void mplus(){
int ans = 1,a,b = 0;
for(int i = 0;i < n;i++){
if(cou[temp[i] - 48]){
a = cou[temp[i] - 48];
for(int j = b;j >= 0;j--){
big[j] *= a;
if(big[j] > 9){
big[j + 1] += big[j] / 10;
big[j] = big[j] % 10;
if(j == b) b++;
}
}
}

}
for(int j = 0;j <= b;j++){
if(big[j] > 9){
big[j + 1] += big[j] / 10;
big[j] = big[j] % 10;
if(j == b) b++;
}
}
for(int r = b;r >= 0;r--)cout<<big[r];
}

int main(){
init();
fshort();
mplus();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: