zoukankan      html  css  js  c++  java
  • 【BZOJ1703】【usaco2007margold】ranking the cows 奶牛的魅力排名

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

    原题:

    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;
    }*/
    

    反例很简单,请自己手玩

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

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int read(){int z=0,mark=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mark;
    11 }
    12 struct ddd{int next,y;}e[11000];  int LINK[1100],ltop=0,rd[1100],cd[1100];
    13 inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;cd[x]++;rd[y]++;}
    14 int n,m;
    15 //int QUEUE[1100000],head=0;
    16 int ans=0;
    17 bool flag[1100];
    18 int f[1100];
    19 int visited[1100];
    20 int max_heap[1100],size=0;
    21 void push(int x){
    22     max_heap[size]=x;
    23     int current=size,father=(size-1)>>1;
    24     while(f[max_heap[current]]>f[max_heap[father]] && father>=0){
    25         swap(max_heap[current],max_heap[father]);
    26         current=father,father=(current-1)>>1;
    27     }
    28     size++;
    29 }
    30 void updata(int x){
    31     int lchild=(x<<1)+1,rchild=(x<<1)+2;
    32     int max_id=x;
    33     if(lchild<size && f[max_heap[lchild]]>f[max_heap[max_id]])  max_id=lchild;
    34     if(rchild<size && f[max_heap[rchild]]>f[max_heap[max_id]])  max_id=rchild;
    35     if(max_id!=x){
    36         swap(max_heap[x],max_heap[max_id]);
    37         updata(max_id);
    38     }
    39 }
    40 void pop(){
    41     swap(max_heap[0],max_heap[size-1]);
    42     size--;
    43     updata(0);
    44 }
    45 /*void dfs(int x){注意这样可能会有重复的:(1,2),(3,2)
    46     f[x]=1;
    47     for(int i=LINK[x];i;i=e[i].next){
    48         if(!f[e[i].y])  dfs(e[i].y);
    49         f[x]+=f[e[i].y];
    50     }
    51 }*/
    52 /*int dfs(int x){这样也可能会有重复的,比如(1,2),(2,3),(1,3)
    53     int z=1;
    54     for(int i=LINK[x];i;i=e[i].next)  z+=dfs(e[i].y);
    55     return z;
    56 }*/
    57 int dfs(int x,int y){
    58     int z=1;
    59     for(int i=LINK[x];i;i=e[i].next)if(visited[e[i].y]!=y){
    60         visited[e[i].y]=y;
    61         z+=dfs(e[i].y,y);
    62     }
    63     return z;
    64 }
    65 int main(){//freopen("ddd.in","r",stdin);
    66     memset(flag,0,sizeof(flag));
    67     cin>>n>>m;
    68     int _left,_right;
    69     while(m --> 0){//趋向于
    70         _left=read(),_right=read();
    71         insert(_left,_right);
    72     }
    73     //for(int i=1;i<=n;++i)if(!rd[i])  QUEUE[++head]=i,++cnt;
    74     for(int i=1;i<=n;++i)  ans+=dfs(i,i)-1;
    75     //for(int i=1;i<=n;++i)if(!rd[i])  push(i);
    76     /*for(int i=1;i<=n;++i){
    77         cout<<rd[max_heap[0]]<<endl;
    78         pop();
    79     }*/
    80     /*while(size){
    81         //cout<<ans<<" "<<cnt<<endl;
    82         ans+=size-1;
    83         int max_id=max_heap[0];  pop();
    84         for(int i=LINK[max_id];i;i=e[i].next){
    85             rd[e[i].y]--;
    86             if(!rd[e[i].y])  push(e[i].y);
    87         }
    88         //cout<<max_id<<endl;
    89     }*/
    90     cout<<n*(n-1)/2-ans<<endl;
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    在Leangoo里怎么修改昵称,简称,头像?
    在Leangoo里怎么找到用户中心?
    Maven相关: An internal error occurred during: "Updating Maven Project". java.lang.NullPointerException
    拦截器与过滤器
    Jfinal基础学习(一)
    mysql中添加一个和root一样的用户用于远程连接
    安卓模拟器安装apk,上网
    简单了解ddos攻击
    eclipse报An error has occurred,See error log for more details. java.lang.NullPointerException错误
    eclipse color themes 让eclipse编码好看点
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6391311.html
Copyright © 2011-2022 走看看