想的时间比较长所以看题解了= =

原题:

Fj有N(N<=1000)头牛,每头牛都有独一无二的正整数 魅力值,Fj想让他们按
魅力值排序。

Fj已经知道M(1<=M<=10000)对奶牛的魅力值,但他发现,他还需要再做一张关

于另外C对奶牛的魅力值比较,才能推断出所有奶牛的魅力值的顺序。
现在请你帮他 算出最小的C值。

刚在拓扑排序方向上想,思路是每次选一个入度为0的点,让这个点向其它所有入度为0的点连边,然后这个点就是目前最高点了,然后就可以删掉不管了,所以可以直接删掉这个点

为了保证最坏情况所以每次删掉的点是所有入度为0的点中从这个点出发能到达的点最多的点

然后用堆搞一下,发现答案不对?
手玩小数据没问题,想了将近一下午无果,遵循经很多神犇"想的时间太长就不要再想"的建议,选择看题解

正解是用减法原理,确定完整的关系需要知道n*(n-1)/2条关系,已知的关系就是每个点能到达的点的个数的和,dfs搞一搞就可以了

然后遇到两个小问题,就是下面这两个dfs都是不对的:

/*void dfs(int x){注意这样可能会有重复的
f[x]=1;
for(int i=LINK[x];i;i=e[i].next){
if(!f[e[i].y]) dfs(e[i].y);
f[x]+=f[e[i].y];
}
}*/
/*int dfs(int x){这样也可能会有重复的
int z=1;
for(int i=LINK[x];i;i=e[i].next) z+=dfs(e[i].y);
return z;
}*/

反例很简单,请自己手玩

代码(我直接在原来堆的错误写法上改的,有一个堆还有各种乱搞,所以代码比较长= =):

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
struct ddd{int next,y;}e[]; int LINK[],ltop=,rd[],cd[];
inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;cd[x]++;rd[y]++;}
int n,m;
//int QUEUE[1100000],head=0;
int ans=;
bool flag[];
int f[];
int visited[];
int max_heap[],size=;
void push(int x){
max_heap[size]=x;
int current=size,father=(size-)>>;
while(f[max_heap[current]]>f[max_heap[father]] && father>=){
swap(max_heap[current],max_heap[father]);
current=father,father=(current-)>>;
}
size++;
}
void updata(int x){
int lchild=(x<<)+,rchild=(x<<)+;
int max_id=x;
if(lchild<size && f[max_heap[lchild]]>f[max_heap[max_id]]) max_id=lchild;
if(rchild<size && f[max_heap[rchild]]>f[max_heap[max_id]]) max_id=rchild;
if(max_id!=x){
swap(max_heap[x],max_heap[max_id]);
updata(max_id);
}
}
void pop(){
swap(max_heap[],max_heap[size-]);
size--;
updata();
}
/*void dfs(int x){注意这样可能会有重复的:(1,2),(3,2)
f[x]=1;
for(int i=LINK[x];i;i=e[i].next){
if(!f[e[i].y]) dfs(e[i].y);
f[x]+=f[e[i].y];
}
}*/
/*int dfs(int x){这样也可能会有重复的,比如(1,2),(2,3),(1,3)
int z=1;
for(int i=LINK[x];i;i=e[i].next) z+=dfs(e[i].y);
return z;
}*/
int dfs(int x,int y){
int z=;
for(int i=LINK[x];i;i=e[i].next)if(visited[e[i].y]!=y){
visited[e[i].y]=y;
z+=dfs(e[i].y,y);
}
return z;
}
int main(){//freopen("ddd.in","r",stdin);
memset(flag,,sizeof(flag));
cin>>n>>m;
int _left,_right;
while(m --> ){//趋向于
_left=read(),_right=read();
insert(_left,_right);
}
//for(int i=1;i<=n;++i)if(!rd[i]) QUEUE[++head]=i,++cnt;
for(int i=;i<=n;++i) ans+=dfs(i,i)-;
//for(int i=1;i<=n;++i)if(!rd[i]) push(i);
/*for(int i=1;i<=n;++i){
cout<<rd[max_heap[0]]<<endl;
pop();
}*/
/*while(size){
//cout<<ans<<" "<<cnt<<endl;
ans+=size-1;
int max_id=max_heap[0]; pop();
for(int i=LINK[max_id];i;i=e[i].next){
rd[e[i].y]--;
if(!rd[e[i].y]) push(e[i].y);
}
//cout<<max_id<<endl;
}*/
cout<<n*(n-)/-ans<<endl;
return ;
}

【BZOJ1703】【usaco2007margold】ranking the cows 奶牛的魅力排名的更多相关文章

  1. Bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名 传递闭包,bitset

    1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 323  Solved ...

  2. BZOJ1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

    n<=1000头牛各有一个未知值Ai,已知m<=10000条形如Ax>Ay的不等关系,求将整个序列排序的最少比较次数. Aa>Ab,Ab>Ac -------> A ...

  3. bzoj:1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

    Description     农夫约翰有N(1≤N≤1000)头奶牛,每一头奶牛都有一个确定的独一无二的正整数产奶率.约翰想要让这些奶牛按产奶率从高到低排序.    约翰已经比较了M(1≤M≤100 ...

  4. 【dfs】BZOJ1703-[Usaco2007 Mar]Ranking the Cows 奶牛排名

    [题目大意] 农夫约翰有N(1≤N≤1000)头奶牛,每一头奶牛都有一个确定的独一无二的正整数产奶率.约翰想要让这些奶牛按产奶率从高到低排序,约翰已经比较了M(1≤M≤10000)对奶牛的产奶率,但他 ...

  5. 【BZOJ】1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

    [题意]给定n头牛和m对大小关系,求最坏情况下至少还需要比较几对奶牛的大小(在未确定顺序的奶牛对中随机比较) [算法]floyd求传递闭包 [题解]可达说明大小已知,则不可达点对数量就是最少比较次数. ...

  6. bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名【bitset+Floyd传递闭包】

    把关系变成有向边,稍微想一下就是要求在有向图中不能到达的点对个数,这个可以用Floyd传递闭包来做,但是n^3的复杂度跑不了1000 考虑bitset优化! 因为传递过程只会出现0和1,用bitset ...

  7. poj_3275 Ranking the cows

    Ranking the cows Description Each of Farmer John's N cows (1 ≤ N ≤ 1,000) produces milk at a differe ...

  8. poj 3275 "Ranking the Cows"(DFS or Floyd+bitset<>)

    传送门 题意: 农场主 FJ 有 n 头奶牛,现在给你 m 对关系(x,y)表示奶牛x的产奶速率高于奶牛y: FJ 想按照奶牛的产奶速率由高到低排列这些奶牛,但是这 m 对关系可能不能精确确定这 n ...

  9. 【BZOJ1720】[Usaco2006 Jan]Corral the Cows 奶牛围栏 双指针法

    [BZOJ1720][Usaco2006 Jan]Corral the Cows 奶牛围栏 Description Farmer John wishes to build a corral for h ...

随机推荐

  1. Python 爬虫-股票数据的Scrapy爬虫

    2017-08-06 19:52:21 目标:获取上交所和深交所所有股票的名称和交易信息输出:保存到文件中 技术路线:scrapy 获取股票列表:东方财富网:http://quote.eastmone ...

  2. CodeSmith公共类维护

    CodeSmith在使用过程中,我们经常会出现同一个方法在不同的页面调用,如果我们在每个页面都写一个这样的方法,那么代码量非常大,同时如果以后需要修改也要在每个页面分别去修改,这无疑是劳命伤财,如果能 ...

  3. Java注解 框架开发之Java注解的妙用

    原文出处: locality 注解的好处: 1.能够读懂别人写的代码,特别是框架相关的代码. 2.本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程 ...

  4. python 在 Windows Server 2008 r2 上 安装失败

    Microsoft Visual C++ 2008 Redistributable Package link (x86): https://www.microsoft.com/en-us/downlo ...

  5. hdoj2476 String painter

    题意:有一刷子,能将区间内涂成同一字母.给出src,dst串,问最少涂几次? 用dp[i][j]表示区间[i,j]内最少涂的次数.len=1,2时很明显.len=3时,dp[i][j]要么就在dp[i ...

  6. hdu-4289 最大流Dinic模板题

    拆点,套模板. 详情见代码. // // main.cpp // hdu_4289 // // Created by Luke on 16/8/29. // Copyright © 2016年 Luk ...

  7. git 添加tag

    前言 什么是tag?tag是节点的意思,一般在上线的时候使用.比如说:你在本地做了好几个功能,然后把这些功能提交到了上线的分支上,某个时刻,你想上线你的新功能,这个时候你需要你个tag来标记一下,告诉 ...

  8. CoderForce 180D-Name (构造+回溯)

    题目大意:给两个字符串s,t,用s中的字符重新组合构造出按字典序最小的但比t大的新字符串. 题目分析:先统计s中各个字母出现的次数,然后从t的左端向右端依次构造出新串的每一位上的字母.这个过程我是用回 ...

  9. POJ-1511 Invitation Cards (双向单源最短路)

    Description In the age of television, not many people attend theater performances. Antique Comedians ...

  10. Leetcode 79

    //这是我写过最难的递归了...//class Solution { public: bool exist(vector<vector<char>>& board, s ...