原题: http://poj.org/problem?id=1975
这题一开始没有想到floyd,就去搜索,结果还过了,虽然时间很长用了200+ms,但也是挺爽,后来去查才知道floyd才是解题方案,下面是两种方法
其实佛洛依德很好用,可以存负权值边而且代码很容易记住,就是复杂度有点高,要记住....求任意两点的最短路,或者关系,首选floyd
floyd 16ms
#include<cstdio>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int dp[100][100]={0};
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d %d",&a,&b);
dp[a][b]=1;//a比b重
dp[b][a]=-1; //a比b轻
}
//floyd
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dp[i][k]==1 && dp[k][j]==1)
{
dp[i][j]=1;
}
if(dp[i][k]==-1 && dp[k][j]==-1)
{
dp[i][j]=-1;
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
int da=0;
int xiao=0;
for(int j=1;j<=n;j++)
{
if(dp[i][j]==1)
{
xiao++;
}
if(dp[i][j]==-1)
{
da++;
}
}
if(xiao>n/2 || da>n/2)//判断是否满足
{
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
暴搜 204ms
#include<cstdio>
#include<set>
#include<memory.h>
using namespace std;
struct Node
{
set<int>max;
set<int>min;
}node[100];
int visit[100];
void find(int id)//找比编号id大的元素
{
if(visit[id]==1)
{
return ;
}
if(node[id].max.size()==0)
{
return ;
}
set<int>::iterator it=node[id].max.begin();
while(it!=node[id].max.end())
{
find(*it);//前一个的max先求好了.
node[id].max.insert(node[*it].max.begin(),node[*it].max.end());
it++;
}
visit[id]=1;
}
void find2(int id)//找比编号id小的元素
{
if(visit[id]==1)
{
return ;
}
if(node[id].min.size()==0)
{
return ;
}
set<int>::iterator it=node[id].min.begin();
while(it!=node[id].min.end())
{
find2(*it);//前一个的min先求好了.
node[id].min.insert(node[*it].min.begin(),node[*it].min.end());
it++;
}
visit[id]=1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d %d",&n,&m);
memset(visit,0,sizeof(visit));
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d %d",&a,&b);
node[a].min.insert(b);
node[b].max.insert(a);
}
// if(m<)
// {
// printf("0\n");
// continue;
// }
int ans=0;
//遍历寻找
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
find(i);
}
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
find2(i);
int c1=node[i].max.size();
int c2=node[i].min.size();
// if(c2>r|| c1>n-(r+1))//判断是否满足
// {
// ans++;
// }
if(c2>n/2 || c1>n/2)
{
ans++;
}
}
for(int i=1;i<=n;i++)//清空
{
node[i].max.clear();
node[i].min.clear();
}
printf("%d\n",ans);
}
return 0;
}