基础的建边

const int N=100010; 
vector<int>g[N];
//基础建边 
void way1(int x,int y){
    g[x].push_back(y); //加边方式 
    int sz=g[x].size(); //遍历方式 
    for(int i=0;i<sz;i++){
        int to=g[x][i];
    }
}
//链式前向星 
int tot,ver[N<<1],next[N<<1],head[N];
//tot 用来编号,ver数组代表第N条边连出去的下一个点是什么,
//next数组表示当前边的上一条边,head 数组指向这一顶点连接下的最后一个 
void add(int u,int v){//添加一条从u到v的边 
    ++tot;
    ver[tot]=v;
    next[tot]=head[u];
    head[u]=tot;
}
void way2(){
    add(x,y);
    for(int i=head[u];i;i=next[i]){
        int to=ver[i];
        
    } 
}
int main()
{
    memset(head,0,sizeof head);
 } 

BFS(广度优先搜索)

 

例题

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.

InputThe input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’    express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
OutputFor each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.Sample Input

4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Sample Output

66
88
66

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#define pii pair<int,int>
using namespace std;
const int N=200+10;
const int M=10;
const int inf=0x3f3f3f3f;
char s[N][N];
int sx[M];
int sy[M];

int n,m,dis[M][N][N];
int dx[M]={0,0,1,-1};//表示当前的点能够坐标变化的方式 
int dy[M]={1,-1,0,0};//x,y相互堆成,表示每次能变化的量 
void bfs(int id)
{
    queue<pii>q;//先进先出 
    q.push(make_pair(sx[id],sy[id]));
    dis[id][sx[id]][sy[id]]=0;
    while(!q.empty())
    {
        int x=q.front().first,y=q.front().second;
        q.pop();//用完之后删掉 
        for(int i=0;i<4;i++)
        {
            int xx=x+dx[i],yy=y+dy[i]; //下一步要走的点 
            if(1<=xx&&xx<=n&&1<=yy&&yy<=m&&dis[id][xx][yy]==inf&&s[xx][yy]!='#')
            {//前面的限制是范围,后面的限制是不能重复走一个点,最后一个条件是他没碰到障碍物 
                dis[id][xx][yy]=dis[id][x][y]+1;//变为出发点+1的距离 
                q.push(make_pair(xx,yy));
            }
        }
    }
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(dis,inf,sizeof dis);
        for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(s[i][j]=='Y') sx[0]=i,sy[0]=j;
                if(s[i][j]=='M') sx[1]=i,sy[1]=j;
            }
        }
        bfs(0),bfs(1);//两个人,各自bfs一次 
        int res=inf;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(s[i][j]=='@')
            {
                res=min(res,dis[0][i][j]+dis[1][i][j]);
            }
        }
        cout<<res*11<<endl;
     } 
}

DFS(深度优先搜索~)

例题

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。Sample Input

1
8
5
0

Sample Output

1
92
10
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#define pii pair<int,int>
using namespace std;
const int N=10+10;
const int M=10;
const int inf=0x3f3f3f3f;
int f[N],vis[N],n,cnt; //vis[i]代表第i列之前已经被第vis[i]行放置 
bool check(int row,int col) //判断第row行,col列能否放置旗子 
{
    if(vis[col]) return false; //判断当前行能否放置 
    for(int i=1;i<=n;i++) //对角线上是否能放置 
    {
        if(vis[i]&&abs(i-col)==abs(vis[i]-row)) return false;
    }
    return true;
}
void dfs(int now) //now表示当前准备放置第now行 
{
    if(now==n+1) //判断是否对答案有贡献 
    {
        cnt++;
        return ;
    }
    for(int i=1;i<=n;i++)
    {
        if(check(now,i)) //now行,i列能不能放置旗子 
        {
            vis[i]=now; //第i列已经由第now行放置 
            dfs(now+1); //递归,放置下一行 
            vis[i]=0; //还原, 
        }
    }
}
int main()
{
    for(n=1;n<=10;n++)
    {
        memset(vis,0,sizeof vis);
        cnt=0;
        dfs(1);
        f[n]=cnt;
     } 
    int x;
    while(scanf("%d",&x)!=EOF)
    {
        if(x==0) break;
        printf("%d\n",f[x]);
    }
    
} 

 拓扑排序题

ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas. When someone has questions, many warm-hearted cows like Lost will come to help. Then the one being helped will call Lost "master", and Lost will have a nice "prentice". By and by, there are many pairs of "master and prentice". But then problem occurs: there are too many masters and too many prentices, how can we know whether it is legal or not?

We all know a master can have many prentices and a prentice may have a lot of masters too, it's legal. Nevertheless,some cows are not so honest, they hold illegal relationship. Take HH and 3xian for instant, HH is 3xian's master and, at the same time, 3xian is HH's master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not.

Please note that the "master and prentice" relation is transitive. It means that if A is B's master ans B is C's master, then A is C's master.

InputThe input consists of several test cases. For each case, the first line contains two integers, N (members to be tested) and M (relationships to be tested)(2 <= N, M <= 100). Then M lines follow, each contains a pair of (x, y) which means x is y's master and y is x's prentice. The input is terminated by N = 0.
TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,..., N-1). We use their numbers instead of their names.OutputFor each test case, print in one line the judgement of the messy relationship.
If it is legal, output "YES", otherwise "NO".Sample Input

3 2
0 1
1 2
2 2
0 1
1 0
0 0

Sample Output

YES
NO
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#define pii pair(int,int)
using namespace std;
const int M=1e4+10; 
const int N=1e2+10;
int m,n;
vector<int> g[N];
int ma[N];
int temp(){
    queue<int> q;
    for(int i=0;i<n;i++){
        if(!ma[i]) q.push(i);//从0到n-1,各个数,进行枚举,看哪个为0,以它为起始点 
    }
    while(!q.empty()){
        int x=q.front();//拿出最先进入的那个值,即那个度不为0的数,开始删它对他的父的影响 
        q.pop();//每次都要删除
        int sz=g[x].size();//关于x作为子,他有多少个父,每个都要删 
        for(int i=0;i<sz;i++){
            int y=g[x][i];//每个对应的父 
            if(--ma[y]==0) q.push(y);//如果 x是y唯一的子,那么在删除x后,y将变成度为0的一个点,在对他进行清算 
        } 
    }
    for(int i=0;i<n;i++) {
        if(ma[i]) return 0;//一旦构成了环,那么是删不完的,所以返回0 
    }
    return 1;
    
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF&&m&&n)
    {    for(int i=0;i<n;i++){
        g[i].clear();//因为有多次,所以每次要先清空 
        ma[i]=0;//存储度的数组,每次一开始都全为0 
    }
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d %d",&x,&y);
            g[x].push_back(y);//把x和y的对应关系通过vector联系起来 
            ma[y]++; //y的度+1 
        } 
        if(temp()) puts("YES");
        else puts("NO"); 
    }
}