贴代码

2009-03-16 来自 · 留下评论 

这是一篇代码大杂烩,原来的博客里分成了好多篇发布。这次博客重整,把它们全合成了一篇。请点下面的链接进入阅读。代码较多,请耐心等待。

贴代码—排序算法

马上就要省选了,这几天练习基础算法。排序是基础中的基础,所以先写排序代码。下面的代码基本上用了模板,所以应该是能广泛适用的。(只要重载小于操作符就可以了)当然这里都是最简单的排序算法,放在这里也仅仅是用来备忘。代码巨丑,看之前做好心理准备。

数据产生器

#include <cstdio>
#include <ctime>
#include <cstdlib>
 
int main()
{
    srand( time( NULL ) );
    int n;
    scanf( "%d" , &n );
    FILE* fout = fopen( "sort.in" , "w" );
    fprintf( fout , "%d\n" , n );
    for( int i = 1 ; i <= n ; ++ i ) {
        fprintf( fout , "%d\n" , rand() % 100000 );
    }
    fclose( fout );
}

冒泡排序

template < typename T > void bubSort( T* arr , int st , int ed )
{
    for( int i = st ; i <= ed ; ++ i ) {
        for( int j = ed ; j > i ; -- j ) {
            if ( arr[ j ] < arr[ j - 1 ] ) {
                T t = arr[ j ];
                arr[ j ] = arr[ j - 1 ];
                arr[ j - 1 ] = t;
            }
        }
    }
}

选择排序

template < typename T > void selSort( T* arr , int st , int ed )
{
    for( int i = st ; i <= ed ; ++ i ) {
        for( int j = i + 1 ; j <= ed ; ++ j ) {
            if ( arr[ j ] < arr[ i ] ) {
                T t = arr[ j ];
                arr[ j ] = arr[ i ];
                arr[ i ] = t;
            }
        }
    }
}

插入排序

template < typename T > void insSort( T* arr , int st , int ed )
{
    for( int i = st + 1 ; i <= ed ; ++ i ) {
        int j = i; T cur = arr[ i ];
        while ( cur < arr[ j - 1 ] ) {
            arr[ j ] = arr[ j - 1 ];
            -- j;
        }
        arr[ j ] = cur;
    }
}

快速排序

template < typename T > void qSort( T* arr , int st , int ed )
{
    int i = st , j = ed; T mid = arr[ ( st + ed ) / 2 ];
    do {
        while ( arr[ i ] < mid ) ++ i;
        while ( mid < arr[ j ] ) -- j;
        if ( i <= j ) {
            T  t = arr[ i ]; arr[ i ] = arr[ j ]; arr[ j ] = t;
            ++ i; -- j;
        }
    } while ( i <= j );
    if ( st < j ) qSort( arr , st , j );
    if ( i < ed ) qSort( arr , i , ed );
}

归并排序,这里写得不好,见谅。

int tmp[ MAX_N + 1 ];
 
template < typename T > void mergeSort( T* arr , int st , int ed )
{
    if ( st >= ed ) return;
    int mid = ( st + ed ) / 2;
    mergeSort( arr , st , mid );
    mergeSort( arr , mid + 1 , ed );
    for( int i = st ; i <= ed; ++ i ) tmp[ i ] = arr[ i ];
    int h1 = st , h2 = mid + 1 , cur = st;
    while ( cur <= ed ) {
        if (  tmp[ h1 ] < tmp[ h2 ] && h1 <= mid || h2 > ed ) {
            arr[ cur++ ] = tmp[ h1 ++ ];
        } else {
            arr[ cur++ ] = tmp[ h2 ++ ];
        }
    }
}

堆排序,只有上浮下沉的过程,怎么实现排序请查找相关资料。

template< typename T > void sink( T* heap , int len , int k )
{
    while ( k * 2 <= len ) {
        int cur = k * 2;
        if ( cur + 1 <= len && heap[ cur + 1 ] < heap[ cur ] ) ++ cur;
        if ( heap[ k ] <= heap[ cur ] ) break;
        T t = heap[ k ];
        heap[ k ] = heap[ cur ];
        heap[ cur ] = t;
        k = cur;
    }
}
 
template< typename T > void swim( T* heap , int len , int k )
{
    while ( k > 1 ) {
        int cur = k / 2;
        k = cur * 2;
        if ( k + 1 <= len && heap[ k + 1 ] < heap[ k ] ) ++ k;
        if ( heap[ cur ] <= heap [ k ] ) break;
        T t = heap[ k ];
        heap[ k ] = heap[ cur ];
        heap[ cur ] = t;
        k = cur;
    }
}

线性排序没怎么写,只有一个没有通用性的计数排序,在这里就不贴了。

贴代码—网络流及二分图匹配

今天写了不少,明天还有最后一天,我要把能写的都写写完,准备上战场啦!这里是网络流/匹配。

二分图最大匹配:匈牙利算法

int n , m;
 
bool map[ MAX_N + 1 ][ MAX_M + 1 ];
 
int lLink[ MAX_N + 1 ] , rLink[ MAX_M + 1 ];
 
bool vis[ MAX_M + 1 ];
bool extPath( int cur )
{
    for( int i = 1 ; i <= m ; ++ i ) {
        if ( !vis[ i ] && map[ cur ][ i ] ){
            vis[ i ] = true;
            if ( rLink[ i ] == 0 || extPath( rLink[ i ] ) ) {
                lLink[ cur ] = i;
                rLink[ i ] = cur;
                return true;
            }
        }
    }
    return false;
}
 
int match()
{
    int ans = 0;
    for( int i = 1 ; i <= n ; ++ i ) {
        for( int j = 1 ; j <= m ; ++ j ) {
            if ( map[ i ][ j ] && rLink[ j ] == 0 ) {
                lLink[ i ] = j;
                rLink[ j ] = i;
                ++ ans;
                break;
            }
        }
    }
 
    for( int i = 1 ; i <= n ; ++ i ) {
        if ( lLink[ i ] == 0 ) {
            memset( vis , 0 , sizeof( vis ) );
            if ( extPath( i ) ) {
                ++ ans;
            }
        }
    }
 
    return ans;
}

最大流:Dinic算法

 
 
const int INF = 10000000;
const int MAX_V = 1000 , MAX_E = MAX_V * MAX_V;
 
struct Edge
{
    int to , cap;
    int bro, next;
} edge[ MAX_E * 2 + 1 ];
int eCnt;
int hLink[ MAX_V + 1 ];
 
void _ins( int from , int to , int cap , int bro )
{
    ++ eCnt;
    edge[ eCnt ].to = to; edge[ eCnt ].bro = bro;
    edge[ eCnt ].cap = cap;
    edge[ eCnt ].next = hLink[ from ]; hLink[ from ] = eCnt;
}
 
void ins( int from , int to , int cap )
{
    _ins( from , to , cap , eCnt + 2 );
    _ins( to , from , 0 , eCnt );
}
 
int S , T;
int level[ MAX_V + 1 ];
int queue[ MAX_V + 1 ];
 
bool BFS()
{
    memset( level , 0 , sizeof( level ) );
    int head = 0 , tail = 1;
    queue[ head ] = S; level[ S ] = 1;
    while( head != tail ) {
        int cur = queue[ head ++ ];
        for( int i = hLink[ cur ]; i ; i = edge[ i ].next ) {
            if ( edge[ i ].cap == 0 ) continue;
            int nxt = edge[ i ].to;
            if ( level[ nxt ] ) continue;
            level[ nxt ] = level[ cur ] + 1;
            queue[ tail ++ ] = nxt;
        }
    }
    return level[ T ];
}
 
int stack[ MAX_V + 1 ];
int reach[ MAX_V + 1 ];
int last[ MAX_V + 1 ];
 
int _maxFlow;
 
void DFS()
{
    int top = 1;
    stack[ top ] = S;
    last[ top ] = hLink[ S ];
    while( top ) {
        if ( stack[ top ] != T ) {
            bool noUse = true;
            for( int i = last[ top ] ; i ; i = edge[ i ].next ) {
                if ( edge[ i ].cap ) {
                    last[ top ] = edge[ i ].next;
                    int nxt = edge[ i ].to;
                    if ( level[ nxt ] != level[ stack[ top ] ] + 1 ) continue;
                    stack[ ++ top ] = nxt;
                    reach[ top ] = i;
                    last[ top ] = hLink[ nxt ];
                    noUse = false;
                    break;
                }
            }
            if ( noUse ) {
                level[ stack[ top ] ] = - 1;
                -- top;
            }
        } else {
            int minVol = INF;
            for( int i = 2 ; i <= top ; ++ i ) {
                if ( edge[ reach[ i ] ].cap < minVol ) {
                    minVol = edge[ reach[ i ] ].cap;
                }
            }
            for( int i = 2 ; i <= top; ++ i ) {
                edge[ reach[ i ] ].cap -= minVol;
                edge[ edge[ reach[ i ] ].bro ].cap += minVol;
            }
            _maxFlow += minVol;
            for( int i = 2 ; i <= top; ++ i ) {
                if ( edge[ reach[ i ] ].cap == 0 ) {
                    top = i - 1;
                }
            }
        }
    }
}
 
int maxFlow()
{
    _maxFlow = 0;
    while( BFS() ) {
        DFS();
    }
    return _maxFlow;
}

其实这里还缺KM和费用流。KM压根不会,费用流就写个最短增广路吧,这里曾经贴过。

重视代码重用是个好习惯。等哪天转ACM了应该会有不少优势。已经开始憧憬ACM了,让我考好点,去趟NOI早点把大学定掉开始ACM吧!

贴代码—数学算法

欧几里德算法、扩展欧几里德算法

void extendEuclid( int a , int b , int& x , int& y )
{
    if ( b == 0 ) {
        x = 1 , y = 0;
    } else {
        int tx , ty;
        extendEuclid( b , a % b , tx , ty );
        x = ty; y = tx - ( a / b ) * ty;
    }
}
 
int gcd( int a , int b )
{
    return b ? gcd( b , a % b ) : a;
}

判断是否是素数

#include <iostream>
#include <fstream>
 
using namespace std;
 
const int MAX_N = 1000000;
 
bool able[ MAX_N + 1 ];
int pList[ MAX_N + 1 ]; int pCnt;
 
int main()
{
    for( int i = 2 ; i <= MAX_N ; ++ i ) able[ i ] = true;
    for( int i = 2 ; i <= MAX_N ; ++ i ) {
        if ( able[ i ] ) pList[ ++pCnt ] = i;
        for( int j = i + i ; j <= MAX_N ; j += i ) able[ j ] = false;
    }
    int n;
    cin >> n;
    while ( n >= 0 ) {
        bool flag = true;
        for( int i = 1 ; i <= pCnt ; ++ i ) {
            if ( n < pList[ i ] * pList[ i ] ) break;
            if ( n % pList[ i ] == 0 ) {
                flag = false;
                break;
            }
        }
        cout << ( flag ? "YES\n" : "NO\n" );
        cin >> n;
    }
    system( "pause" );
}

高斯消元法

#include <iostream>
#include <cmath>
 
using namespace std;
 
const int MAX_N = 100;
int n , m;
 
struct Arr
{
    double data[ MAX_N + 2 ];
    double& operator[]( int ind ) {
        return data[ ind ];
    }
} equ[ MAX_N + 1 ];
 
void input()
{
    cin >> n; m = n + 1;
    for( int i = 1 ; i <= n ; ++ i ) {
        for( int j = 1 ; j <= m ; ++ j ) {
            cin >> equ[ i ][ j ];
        }
    }
}
 
void makeZero( int std , int cur )
{
    double k = equ[ cur ][ std ] / equ[ std ][ std ];
    for( int i = std ; i <= m ; ++ i ) {
        equ[ cur ][ i ] -= equ[ std ][ i ] * k;
    }
}
 
void process( int cur )
{
    int maxFrom = cur;
    for( int i = cur + 1 ; i <= n ; ++ i ) {
        if ( abs( equ[ maxFrom ][ cur ] ) < abs( equ[ i ][ cur ] ) ) {
            maxFrom = i;
        }
    }
    if ( maxFrom != cur ) {
        Arr t = equ[ cur ];
        equ[ cur ] = equ[ maxFrom ];
        equ[ maxFrom ] = t;
    }
    for( int i = cur + 1 ; i <= n ; ++ i ) {
        makeZero( cur , i );
    }
}
 
double ans[ MAX_N + 1 ];
 
void getAns( int cur )
{
    double rtn = equ[ cur ][ m ];
    for( int i = n ; i > cur ; -- i ) {
        rtn -= equ[ cur ][ i ] * ans[ i ];
    }
    rtn /= equ[ cur ][ cur ];
    if ( abs( rtn ) < 1e-6 ) rtn = 0;
    ans[ cur ] = rtn;
}
 
int main()
{
    input();
    for( int i = 1 ; i <= n ; ++ i ) {
        process( i );
    }
    for( int i = n ; i >= 1 ; -- i ) {
        getAns( i );
    }
    for( int i = 1 ; i <= n ; ++ i ) {
        cout.precision( 0 );
        cout << fixed;
        cout << ans[ i ] << ( i == n ? "\n" : " " );
    }
}

贴代码—凸壳

计算几何都不怎么会,有些知道的从来没写过。唯一会的只有这个凸壳了。这是USACO 5.1 Fencing the Cows的代码,算法是Graham扫描法。

#include <iostream>
#include <fstream>
#include <cmath>
 
using namespace std;
 
ifstream fin( "fc.in" );
ofstream fout( "fc.out" );
 
struct Point
{
    double x , y;
};
 
inline double dis( Point a , Point b )
{
    return sqrt( ( a .x - b.x ) * ( a .x - b.x ) + ( a .y - b.y ) * ( a .y - b.y ) );
}
 
Point operator- ( Point a , Point b )
{
    Point rtn;
    rtn.x = a.x - b.x;
    rtn.y = a.y - b.y;
    return rtn;
}
 
double crossProduct( Point a , Point b )
{
    return a.x * b.y - b.x * a.y;
}
 
Point pStd;
 
bool operator<( Point a, Point b )
{
    return crossProduct( a - pStd , b - pStd ) > 0;
}
 
template< typename T >void qSort( T* arr , int st , int ed )
{
    int i = st , j = ed;
    T mid = arr[ ( st + ed ) / 2 ];
    while( i <= j ) {
        while( arr[ i ] < mid ) ++ i;
        while( mid < arr[ j ] ) -- j;
        if ( i <= j ) {
            T t = arr[ i ]; arr[ i ] = arr[ j ]; arr[ j ] = t;
            ++ i; -- j;
        }
    } while( i <= j );
    if ( st < j ) qSort( arr , st , j );
    if ( i < ed ) qSort( arr , i , ed );
}
 
const int MAX_N = 10000;
Point points[ MAX_N + 2 ];
int n;
 
Point stack[ MAX_N + 2 ];
 
int main()
{
    fin >> n;
    fin >> points[ 1 ].x >> points[ 1 ].y;
    for( int i = 2 ; i <= n ; ++ i ) {
        fin >> points[ i ].x >> points[ i ].y;
        if ( ( points[ i ].x < points[ 1 ].x ) ||
             ( points[ i ].x == points[ 1 ].x && ( points[ i ].y < points[ 1 ].y ) ) ) {
            Point t = points[ 1 ];
            points[ 1 ] = points[ i ];
            points[ i ] = t;
        }
    }
    pStd = points[ 1 ];
    qSort( points , 2 , n );
    points[ ++ n ] = points[ 1 ];
    int top = 0;
    stack[ ++ top ] = points[ 1 ]; stack[ ++ top ] = points[ 2 ];
 
    /*
    for( int i = 1 ; i <= n ; ++ i ) {
        fout << points[ i ].x << " " << points[ i ].y << endl;
    }
    */
 
    for( int i = 3 ; i <= n ; ++ i ) {
        while( top >= 2 && crossProduct( stack[ top ] - stack[ top - 1 ] , points[ i ] - stack[ top - 1 ] ) < 0 ) {
            -- top;
        }
        stack[ ++ top ] = points[ i ];
    }
    double ans = 0;
    for( int i = 2 ; i <= top ; ++ i ) {
        ans += dis( stack[ i ] , stack[ i - 1 ] );
    }
    fout.precision( 2 ); fout << fixed;
    fout << ans << endl;
    fin.close();
    fout.close();
}

贴代码—KMP

本来应该是个字符串大杂烩的,可惜不会扩展KMP、自动机、后缀数组这些强大的东西,弱弱地贴个KMP,供大家鄙视。

 
<pre lang="cpp" colla="-">
#include <iostream>
#include <string>
 
using namespace std;
 
string mod , str;
 
const int MAX_N = 1000000;
int n , m;
int next[ MAX_N + 1 ];
 
void getNext()
{
    int i = 1 , j = 0;
    while( i <= m ) {
        if ( j == 0 || mod[ i ] == mod[ j ] ) {
            ++ i; ++ j;
            if ( mod[ i ] == mod[ j ] ) {
                next[ i ] = next[ j ];
            } else {
                next[ i ] = j;
            }
        } else {
            j = next[ j ];
        }
    }
}
 
string::size_type pos( int i )
{
    int j = 1;
    while( i <= n && j <= m ) {
        if ( str[ i ] == mod[ j ] || j == 0 ) {
            ++ i; ++ j;
        } else {
            j = next[ j ];
        }
    }
    if ( j > m ) {
        return i - j + 1;
    } else {
        return string::npos;
    }
}
 
int main()
{
    cout << "Knuth-Morris-Pratt Algorithm Test" << endl;
    cout << "Input : String Mod_String Starting_Pos" << endl;
    cin >> str >> mod;
    n = str.length(); m = mod.length();
    str = " " + str; mod = " " + mod;
    getNext();
    int oriPos; cin >> oriPos;
    cout << "K-M-P Algorithm  return = " << pos( oriPos ) << endl;
    cout << "C++ Class String return = " << str.find( mod.substr( 1 , m ) , oriPos ) << endl;
    system( "pause" );
}

贴代码—数据结构

明天就要出发了,把这里剩下的贴贴完吧。接下来是数据结构,常用的并查集、堆以及平衡树。

 
堆,好像是是小根堆。
<pre lang="cpp" colla="-">
template< typename T >class Heap
{
    private:
        static const int MAX_N = 1000000;
        T data[ MAX_N + 1 ];
        int n;
        void swim( int cur )
        {
            while( cur > 1 ) {
                int fat = cur / 2;
                cur = fat * 2;
                if ( cur < n && data[ cur + 1 ] < data[ cur ] ) ++ cur;
                if ( data[ cur ] < data[ fat ] ) {
                    T t = data[ cur ];
                    data[ cur ] = data[ fat ];
                    data[ fat ] = t;
                    cur = fat;
                } else {
                    break;
                }
            }
        }
 
        void sink( int cur )
        {
            while( cur <= n ) {
                int fat = cur;
                cur *= 2;
                if ( cur < n && data[ cur + 1 ] < data[ cur ] ) ++ cur;
                if ( cur <= n && data[ cur ] < data[ fat ] ) {
                    T t = data[ cur ];
                    data[ cur ] = data[ fat ];
                    data[ fat ] = t;
                } else {
                    break;
                }
            }
        }
    public:
        Heap()
        {
            n = 0;
        }
        void ins( T node )
        {
            data[ ++ n ] = node;
            swim( n );
        }
 
        T getMin()
        {
            assert( n );
            return data[ 1 ];
        }
 
        void delMin()
        {
            data[ 1 ] = data[ n -- ];
            sink( 1 );
        }
 
        void printAll()
        {
            for( int i = 1 ; i <= n ; ++ i ) {
                cout << data[ i ] << " ";
            }
            cout << endl;
        }
};

并查集

class DisjointSet
{
    private:
        static const int MAX_N = 100000;
        int fat[ MAX_N + 1 ];
        int stack[ MAX_N + 1 ];
    public:
        DisjointSet() {
            for( int i = 1 ; i <= MAX_N ; ++ i ) {
                fat[ i ] = i;
            }
        }
        int findSet( int cur ) {
            int top = 1;
            stack[ top ] = cur;
            while( stack[ top ] != fat[ stack[ top ] ] ) {
                stack[ top + 1 ] = fat[ stack[ top ] ]; ++ top;
            }
            int rtn = stack[ top ];
            for( int i = 1 ; i <= top ; ++ i ) fat[ stack[ i ] ] = rtn;
            return rtn;
        }
        bool isSame( int a , int b ) {
            return findSet( a ) == findSet( b );
        }
        void unionSet( int a , int b ) {
            int fatA = findSet( a ) , fatB = findSet( b );
            fat[ fatA ] = fatB;
        }
};

平衡树,Treap,见这里

贴代码—基础图论算法

这是贴代码系列的最后一部分,也是最最丑的一部分。因为放在这里仅供备忘,所以神牛们将就点吧……

图的点数、边数定义、邻接表的插入。

const int INF = 1000000000;
const int MAX_N = 100, MAX_M = 100000;
int n , m;
 
struct Edge
{
    int tar , weight;
    int next;
} edge[ MAX_M + 1 ];
int lHead[ MAX_N + 1 ]; int eCnt;
 
void ins( int src , int tar , int wei )
{
    ++ eCnt;
    edge[ eCnt ].next = lHead[ src ];
    lHead[ src ] = eCnt;
    edge[ eCnt ].tar = tar;
    edge[ eCnt ].weight = wei;
}

图的遍历,深度优先及广度优先搜索

void bfs( int src )
{
    queue[ head ] = src;
    vis[ src ] = true;
    while ( head != tail ) {
        int cur = queue[ head ++ ];
        fout << "BFS " << cur << endl;
        for( int i = lHead[ cur ] ; i ; i = edge[ i ].next ) {
            if ( !vis[ edge[ i ].tar ] ) {
                vis[ edge[ i ].tar ] = true;
                queue[ tail ++ ] = edge[ i ].tar;
            }
        }
    }
}
 
void dfs( int cur )
{
    vis[ cur ] = true;
    fout << "DFS " << cur << endl;
    for( int i = lHead[ cur ] ; i ; i = edge[ i ].next ) {
        if ( !vis[ edge[ i ].tar ] ) {
            dfs( edge[ i ].tar );
        }
    }
}

最小生成树Prim算法。(突然发现少了Kruskal算法,算了就不写了吧)

int dis[ MAX_N + 1 ];
int prim( int src )
{
    int rtn = 0;
    for( int i = 1 ; i <= n ; ++ i ) dis[ i ] = INF;
    dis[ src ] = 0;
    for( int i = 1 ; i <= n ; ++ i ) {
        int minID , min = INF;
        for( int j = 1 ; j <= n ; ++ j ) {
            if ( dis[ j ] < min && !vis[ j ] ) {
                min = dis[ j ];
                minID = j;
            }
        }
        vis[ minID ] = true; rtn += dis[ minID ];
        for( int j = lHead[ minID ] ; j ; j = edge[ j ].next ) {
            if ( edge[ j ].weight < dis[ edge[ j ].tar ] ) {
                dis[ edge[ j ].tar ] = edge[ j ].weight;
            }
        }
    }
    return rtn;
}

常用的两种最短路算法,Dijkstra与SPFA。

int dis[ MAX_N + 1 ];
 
void dijkstra( int src )
{
    for( int i = 1 ; i <= n ; ++ i ) dis[ i ] = INF;
    dis[ src ] = 0;
    for( int i = 1 ; i <= n ; ++ i ) {
        int minID , min = INF;
        for( int j = 1 ; j <= n ; ++ j ) {
            if ( dis[ j ] < min && !vis[ j ] ) {
                min = dis[ j ];
                minID = j;
            }
        }
        vis[ minID ] = true;
        for( int j = lHead[ minID ] ; j ; j = edge[ j ].next ) {
            if ( dis[ minID ] + edge[ j ].weight < dis[ edge[ j ].tar ] ) {
                dis[ edge[ j ].tar ] = dis[ minID ] + edge[ j ].weight;
            }
        }
    }
}
 
void spfa( int src )
{
    queue[ head = 0 ] = src; tail = 1;
    vis[ src ] = true;
    for( int i = 1 ; i <= n ; ++ i ) dis[ i ] = INF;
    dis[ src ] = 0;
    while ( head != tail ) {
        int cur = queue[ head ++ ];
        head %= MAX_N;
        vis[ cur ] = false;
        for( int i = lHead[ cur ]; i ; i = edge[ i ].next ) {
            if ( dis[ cur ] + edge[ i ].weight < dis[ edge[ i ].tar ] ) {
                dis[ edge[ i ].tar ] = dis[ cur ] + edge[ i ].weight;
                if ( !vis[ edge[ i ].tar ] ) {
                    vis[ edge[ i ].tar ] = true;
                    queue[ tail++ ] = edge[ i ].tar;
                    tail %= MAX_N;
                }
            }
        }
    }
}

拓扑排序

void topoSort()
{
    for( int i = 1 ; i <= eCnt ; ++ i ) ++d[ edge[ i ].tar ];
    head = tail = 0;
    for( int i = 1 ; i <= n ; ++ i ) {
        if ( d[ i ] == 0 ) {
            queue[ tail++ ] = i;
        }
    }
    while ( head != tail ) {
        int cur = queue[ head++ ];
        fout << cur << " ";
        for( int i = lHead[ cur ]; i ; i = edge[ i ].next ) {
            if ( -- d[ edge[ i ].tar ] == 0 ) queue[ tail ++ ] = edge[ i ].tar;
        }
    }
}
关于 BillWSY

这是一个个人的Blog。我是一名普通的大学生,平时喜欢玩玩电脑,参加信息学奥赛。生活中总有那么一点东西,希望与大家一同分享。欢迎大家来到我的Blog。

说出你的看法

请告诉我们你们有什么看法...
同时如果你想在评论旁边显示一个图片,可以到gravatar申请!