奖学金 灵活的拓扑排序

来源:互联网 发布:薄膜键盘推荐 知乎 编辑:程序博客网 时间:2024/06/02 13:59
  1. 对先遍历后处理要理解的深刻。
  2. 从下往上遍历通过传参数改变父节点的值。
  3. 利用vector存图可以大大减少空间和时间的开销。

算法一定要灵活的掌握,不能死搬硬套,而且对先遍历后处理的思想理解的要深刻,还有从下往上遍历时通过传参改变父节点值。
利用vector存图可以大大减少空间和时间的开销,但是要resize()哦。
题目:

00030:奖学金查看 提交 统计 提问总时间限制: 1000ms 内存限制: 128000kB描述期末考试终于完了,老班决定召开班委会,内容嘛,则是可爱的奖学金的问题((*^__^*)),她叫来了一些班委,每位班委提出了自己的意见:“我认为同学a的奖学金应该比b多!”老班决定要找出一种奖学金方案,满足各位班委的意见,且同时使得总奖学金数最少。每位同学奖学金最少为100元且都为整数。【输入】    第一行两个整数n,m,表示同学总数和班委意见数n<=10000,m<=20000;    以下m行,每行2个整数a,b,表示某个班委认为第a号同学奖学金应该比第b号同学高。输入第一行两个整数n,m,表示同学总数和班委意见数;以下m行,每行2个整数a,b,表示某个班委认为第a号同学奖学金应该比第b号同学高。输出若无法找到合法方案,则输出“impossible”(不含引号);否则输出一个数表示最少总奖学金。样例输入2 11 2样例输出201
#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cmath>#include<cctype>#include<string>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<set>#include<map>#include<ctime>#include<vector>#include<fstream>#include<list>using namespace std;vector<vector<int> >G;int visited[10001];int n,s = 0;int value[10001];int indexx;bool dfs(int child,int parent){    visited[child] = -1;    vector<int>::iterator it;    for(it = G[child].begin(); it != G[child].end(); ++it)    {        indexx = *it;        if(visited[indexx] == -1)            return false;        else        {            if(!visited[indexx])            {                if(!dfs(indexx,child))                    return false;            }            else//拓扑排序的灵活处理,<更新>父节点的值            {                if(value[indexx]+1 > value[child])                    value[child] = value[indexx]+1;            }        }    }    visited[child] = 1;    s += 100 + value[child];    if(parent != 0 && value[child]+1 > value[parent])        value[parent] = value[child] + 1;//思路要严密,更新父节点的值    return true;}bool toposort(){    for(int i = 1; i <= n; ++i)    {        if(!visited[i] && !dfs(i,0))           return false;    }    return true;}int main(){    //freopen("F:\\data.txt","r",stdin);//方便调试//    ios::sync_with_stdio(false);//使cin的读入速度接近于scanf    G.clear();    memset(visited,0,sizeof(visited));    memset(value,0,sizeof(value));    int m;    scanf("%d%d",&n,&m);    G.resize(n+1);    int a,b;    for(int i = 1; i <= m; ++i)    {        scanf("%d%d",&a,&b);        G[a].push_back(b);    }    if(toposort())    {        printf("%d\n",s);    }    else        printf("impossible\n");    return 0;}
0 0