USACO 2.1 graph

来源:互联网 发布:手机4g网络信号差 编辑:程序博客网 时间:2024/06/05 17:59

concepts of graph

wiki_link

flood fill algorithm

图论嘿嘿嘿
下学期离散就要开课啦
回忆一下现在还记得的图算法
bfs dfs 并查集 floyd……
好吧还是好好学吧

Notes

  • layout 布局
  • terminology
    • loop
    • multigraph
    • adjacent
    • sparse <-> dense <= edges ~ N(N1)2
    • component
    • strongly connected
    • dag
    • complete
    • bipartite
  • Graph Representation
    • Edge List
    • Adjacency Matrix
    • Adjacency List
      效率
  • Flood fill can be performed three basic ways: depth-first, breadth-first, and breadth-first scanning.

castle

We use a simple recursive flood fill to number each room in the castle, and then look at all the pairs of rooms we can join by knocking out any wall. Since we’re going to use the westernmost and then southernmost square, we need only consider knocking out walls to the north and to the east.
Russ Cox

  • floodfill,有趣的是通过位与来表示墙的存在= =而且建了三个数组来表示状态..(转念一想不如多用几个位也可以..)
  • 然后表示有一些难度= =主要是没有理解题目最后一句话

    Choose the optimal wall to remove from the set of optimal walls by choosing the module farthest to the west (and then, if still tied, farthest to the south). If still tied, choose ‘N’ before ‘E’. Name that wall by naming the module that borders it on either the west or south, along with a direction of N or E giving the location of the wall with respect to the module.

    • 当时就在纠结干嘛比完了NE还要有一次优先级= =直到出了一组所有格子都分开的数据;)
    • 尤其要注意,当存在else时候if中间嵌套if不等价于&&
//两次用dfs floodfill= =void dfs(int x,int y){    area[x][y]=-1;    sym[x][y]=room;    tempsize++;    dfs(...);}//官方省略了第二重,因为用room序号指向了那点的room,然后开roomsize数组//其实审题的时候想到了这个trick..但是做题的时候忘了void floodfill(int x,int y){    area[x][y]=tempsize;    floodfill(...)}//判断函数//官方在这里用了enum使得逻辑更加清晰//代替dx,dy,官方是这样写的/*     if(x > 0 && !(w & Wwest))    number(room, x-1, y);    if(x+1 < wid && !(w & Weast))    number(room, x+1, y);    if(y > 0 && !(w & Wnorth))    number(room, x, y-1);    if(y+1 < ht && !(w & Wsouth))    number(room, x, y+1);也就是说,当判断条件各不相同的时候不妨分开写= =*/inline bool connect(int ax,int ay,int bx,int by,int a,int b){    if (ax==bx)         if (ay<by)             if ((a&4)&&(b&1)) //这里不能用&&写                return false;        else if((a&1)&&(b&4))            return false;    else        if (ax<bx)             if ((a&8)&&(b&2))                 return false;        else if ((a&2)&&(b&8))            return false;    return true;}bool betterpos(int x,int y){    if (y!=posy) {        return y<posy;    }else if (x!=posx)        return x>posx;//注意这里的方向是大于(1W)    return false;}

第二题排序题.

枚举gcd(a,b)<=1的 numerators and denominators对,写个排序函数
- 题解部分内部循环版本gcd

bool rprime(int a, int b){   int r = a % b;   while(r != 0){       a = b;       b = r;       r = a % b;   }   return(b == 1);}

第三题 排序->交换次数

  • 因为数据种类比较少,显然桶排计数.
  • 交换的时候用个栈来表示每组数已经多出来的数
  • 最后一个数就不用算了= =
if num[p]!=k    if the first entry         its stack add and count add    else if the stack is not empty and that number appeared        stack dec    else the number stack add and count add    //because there are only 3 numbers

the algorithm in analysis

count and swap two swap entry

2 1 =>1 2

count left and not arranged entry

3 1 2 =>1 2 3

another

make three backets in[3][3] which means some pos int the other one
from the order 1-2,2-3,1-3,cycle to add min(in[1][2],in[2][1]) and decrese

求最少勺数==

  • 一开始以为是dp 不敢动手…
  • (果然是)目测这道题也是搜索= =回来做.
  • dfs对于nownumber取或不取问题..

    在else里面不用for循环

  • 一开始看错题了以为一个勺子能取很多次= =

    • 然后这里另一个bug产生了无限循环..因为一个勺子取很多次也不一定能达到目标…

    Cows can be fed at most one scoop of any feed type

找n个不大于2b的数distance>=d

暴搜,注意搜索顺序,suc后直接return.

//int Nth_bit = (1 << N) & M;int distance(int a,int b){    int c=(a^b),cnt=0;    while (c) {        if (c&1)            cnt++;        c>>=1;    }    return cnt;}

analysis里面拿了一个数组存

for (a = 0; a < maxval; a++)    for (b = 0; b < maxval; b++) {        dist[a][b] = 0;        for (c = 0; c < B; c++)             if (((1 << c) & a) != ((1 << c) & b))                dist[a][b]++;

BTW..数集搞错了= =(0.. 2b1)

0 0