zoukankan      html  css  js  c++  java
  • POJ 3687 Labeling Balls (拓扑排序)

    题意:给定m个球的关系,求出具有最小字典序的各个球的重量。

    思路:拓扑排序,但是不能建正向图,只能建反向图,具体解释见Answeror牛:

      http://www.answeror.com/archives/23913

    PS:图论中的技巧太多,只靠做题感觉是亡羊补牢,只有把理论知识搞透彻,才能真正明白各个题中隐藏的数学原理,向这样正向和反向图中的细微区别也就yin不了人了...

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 205;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    typedef
    struct{
    int v;
    int next;
    }Edge;

    int index,n,m;
    Edge edge[MAXN
    *MAXN];
    int weight[MAXN],grad[MAXN],net[MAXN];
    bool g[MAXN][MAXN],visit[MAXN];

    void add_edge(const int& u,const int& v)
    {
    edge[index].v
    = v;
    edge[index].next
    = net[u];
    net[u]
    = index++;
    }
    int init()
    {
    index
    = 0;
    CLR(visit,
    0);
    CLR(net,
    -1);
    CLR(grad,
    0);
    CLR(g,
    0);
    return 0;
    }
    int input()
    {
    int i,j,a,b;
    scanf(
    "%d%d",&n,&m);
    for(i = 0; i < m; ++i)
    {
    scanf(
    "%d %d",&a,&b);
    if(!g[b][a])//判重
    {
    g[b][a]
    = true;
    add_edge(b,a);
    //反向图
    ++grad[a];
    }
    }
    return 0;
    }
    int work()
    {
    int i,j,tmp,mmin;
    for(i = 0; i < n; ++i)//拓扑
    {
    for(j = n; j > 0 && grad[j]!=0; --j)
    ;
    if(j <= 0)
    {
    printf(
    "-1\n");
    return 0;
    }
    grad[j]
    = -1;
    weight[j]
    = n-i;
    for(j = net[j]; j != -1; j = edge[j].next)
    --grad[edge[j].v];
    }
    printf(
    "%d",weight[1]);
    for(i = 2; i <= n; ++i)
    printf(
    " %d",weight[i]);
    printf(
    "\n");
    return 0;
    }
    int main()
    {
    int t ;
    IN(t);
    while(t--)
    {
    init();
    input();
    work();
    }
    return 0;
    }
  • 相关阅读:
    零基础学习Java Web开发(一)
    域名的定义
    MyEclipse使用(一)
    VB与C#语言部分不用的地方Part1
    使用XmlWriter创建XML文件
    Spring源码
    Websocket原理
    阿里云
    CSS中position属性( absolute | relative | static | fixed )详解
    C#UDP广域网,局域网通信-原理分析
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1719200.html
Copyright © 2011-2022 走看看