秋季第一周集训

图论

(一)主要讲了图的基本概念,然后讲了图的几种形式,比如二分图,有向图,带权图,邻接矩阵,邻接表等等。
(二)图的存储

1.邻接表:用二维数字存储即可:int graph[num][unm]
优点:适合稠密图;编码非常简短;对边的存储,查询,更新等操作又快又简单,只需要一步就能访问和修改。
缺点:存储复杂度太高,大量的空间会被浪费;一般情况下不能存储重边;
2.邻接表:规模大的系数图一般用邻接表存储
优点:存储效率非常高,只需要与边数成正比的空间
缺点:编比邻接矩阵麻烦一些,访问和修改也慢一些
3.链式前向星:用静态数组模拟邻接表
优点:空间效率最高的一种方法,没有任何浪费,程序简单,能储存重边;
缺点:不方便做删除操作

(三)拓扑排序

拓扑排序的充要条件是他是一个有向无环图。有环图不能进行拓扑排序。
拓扑排序需要用到点的入度和出度的概念
出度:以点u为起点的边的数量称为u的出度。
入度:以点v为终点的边的数量称为的v入度。
拓扑排序无解的判断:如果队列已空,但是还有点未进入队列,那么这些点的入度都不是0,说明不是DAG,不存在拓扑排序。

hdu 1285

图这一块刚刚接触,所以对题目怎么解还是不了解,就先看看大佬的解法,熟悉熟悉模板

#include<bits/stdc++.h>
#define LL long long
#define inf 1<<30
using namespace std;
const int N=505;
int a,b,n,m,top;
struct node
{
    int in;     //  记录入度;
    int out;    //  记录出度;
}s[N];
bool Map[N][N]; //  用来标记a到b
bool vis[N];    //  用来标记是否已经Push输出了;
int st[N];
void Push(int i)    //  存储最后排序结构;
{
    st[++top]=i;
}
void TopSort()
{
    int flag=1;
    while(flag){
        flag=0;     //  用于判断是否全部Push;
        for(int i=1;i<=n;i++){          //  遍历每一个点,
            if(!vis[i]&&s[i].in==0){    //  从小到大找出入度为零的点,然后Push;
                flag=1;
                Push(i);
                vis[i]=true;
                for(int j=1;j<=n;j++){      //  因为i已经输出,所以所有有i到j入度的j的入度都要减一;
                    if(Map[i][j]) --s[j].in;
                }
                break;      //  加一个这个才能够保证是按照从小到大输出;orz....
            }
        }
    }
}
void Print()        //  打印结果;
{
    for(int i=1;i<top;i++) printf("%d ",st[i]);
    printf("%d\n",st[top]);
}
int main()
{
    while(~scanf("%d%d",&n,&m)){
        memset(Map,false,sizeof(Map));
        memset(vis,false,sizeof(vis));
        memset(s,0,sizeof(s));
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            if(!Map[a][b]){     //  数据可能有重复的边,一不小心就WA了;
                s[a].out++;
                s[b].in++;
            }
            Map[a][b]=true;
        }
        top=0;
        TopSort();
        Print();
    }
    return 0;
}

这周好像学的东西不是很多,dfs和bfs当初理解的还不是很透,所以拓扑排序有点看不大懂,下星期决定先把搜索这一块再复习一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值