Comparing Your Heros拓扑序列的数量

给出N行英雄的比较,每一行包含两个英雄的名字,代表第一个英雄比第二个英雄更受欢迎。

英雄的数目不超过16个。问有多少种可能的受欢迎程度的序列满足N行英雄的比较。

由于只有英雄数目不超过16个,可以用二进制来解决。

x的的位表示还有哪些点没有处理。在这些点中选择一个入度没零的点,求剩下的点可能排列的数目。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 #include <stack>
12 #include <list>
13 using namespace std;
14 const int INF=0x5fffffff;
15 const double EXP=1e-8;
16 const int MS=1<<17;
17 int edges[18][18];
18 int in[18];
19 int base[18];
20 int flag[MS];
21 char name[18][15];
22 int n,m;
23
24 int ID(char *s)
25 {
26     for(int i=0;i<n;i++)
27     {
28         if(!strcmp(name[i],s))
29             return i;
30     }
31     strcpy(name[n],s);
32     return n++;
33 }
34
35 int find(int x)   //x的二进制的位表示那些点还没有处理。
36 {
37     if(flag[x]>0)
38         return flag[x];
39     for(int i=0;i<n;i++)
40     {
41         if(in[i]==0&&((x&base[i])==base[i]))
42         {
43             for(int j=0;j<n;j++)
44                 if(edges[i][j])
45                     in[j]--;
46             flag[x]+=find(x^base[i]);//  去掉i点后,剩下的点有多少种可能
47             for(int j=0;j<n;j++)
48                 if(edges[i][j])
49                     in[j]++;
50         }
51     }
52     return flag[x];
53 }
54
55 int main()
56 {
57     char a[15],b[15];
58     for(int i=0;i<17;i++)
59         base[i]=1<<i;
60     while(scanf("%d",&m)!=EOF)
61     {
62         n=0;   //顶点数量
63         int c,d;
64         memset(flag,0,sizeof(flag));
65         memset(edges,0,sizeof(edges));
66         memset(in,0,sizeof(in));
67         for(int i=0;i<m;i++)
68         {
69             scanf("%s%s",a,b);
70             c=ID(a);
71             d=ID(b);
72             edges[c][d]=1;
73             in[d]++;
74         }
75         for(int i=0;i<n;i++)
76             flag[base[i]]=1;
77         int ans=find(base[n]-1);
78         printf("%d\n",ans);
79     }
80     return 0;
81 }
时间: 2024-08-24 02:29:12

Comparing Your Heros拓扑序列的数量的相关文章

求拓扑排序的数量,例题 topcoder srm 654 div2 500

周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are numbered from 0 to N-1. Some pairs of rooms are connected by bidirectional passages. The passages have the topology of a tree. That is, there are exactly N-

图结构练习——判断给定图是否存在合法拓扑序列

图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个有向图,判断该有向图是否存在一个合法的拓扑序列. 输入 输入包含多组,每组格式如下. 第一行包含两个整数n,m,分别代表该有向图的顶点数和边数.(n<=10) 后面m行每行两个整数a b,表示从a到b有一条有向边. 输出 若给定有向图存在合法拓扑序列,则输出YES:否则输出NO. 示例输入 1 0 2 2 1 2 2 1 示例输出 YES NO #inc

图结构练习——判断给定图是否存在合法拓扑序列(sdutoj)

#include<stdio.h>#include<string.h>int d[15],map[15][15],vis[15];int main(){    int i,j,k,f,n,m,u,v;    while(~scanf("%d%d",&n,&m))    {        memset(d,0,sizeof(d));        memset(map,0,sizeof(map));        memset(vis,0,size

拓扑序列 之 hdu 5154 Harry and Magical Computer

/* AOV网(Activity On Vertex Network): 用图来表示工程:其中,用顶点表示活动:弧表示活动之间的制约关系. 工程是否顺利进行?---->AOV网是否存在有向回路 ******************************************* 用产生(包含所有) 顶点序列的方法,顶点序列满足: 在图中,若顶点vi到顶点vj存在路径, 则在序列中,顶点vi领先于顶点vj. 满足上述条件的顶点序列称为拓扑序列, 产生这一序列的过程称为拓扑排序. ********

拓扑序列变形 之 poj 1094 Sorting It All Out

/* 拓扑序列变形 之 poj 1094 Sorting It All Out 变形: 在每消去唯一一个入度为0的点后,只剩下唯一一个入度为0的点. 这样获得的n个点才是排序好的. */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm&

数据结构实践项目——最短路径和拓扑序列

本文是针对[数据结构基础系列(7):图]的第2组实践例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) 0710 生成树的概念 0711 最小生成树的普里姆算法 0712 最小生成树的克鲁斯卡尔算法 0713 从一个顶点到其余各顶点的最短路径 0714 每对顶点之间的最短路径 0715 拓扑排序 0716 AOE网与关键路径 纸上谈兵:"知原理"检验题目 1.针对下面的图1: (图1) (1)写出图的邻接矩阵: (2)按照Prim算

(hdu step 5.2.5)确定比赛名次(求拓扑序列)

题目: 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 337 Accepted Submission(s): 180   Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得

图结构练习——推断给定图是否存在合法拓扑序列(拓扑排序推断环)

图结构练习--推断给定图是否存在合法拓扑序列 Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 给定一个有向图,推断该有向图是否存在一个合法的拓扑序列. 输入 输入包括多组.每组格式例如以下. 第一行包括两个整数n,m.分别代表该有向图的顶点数和边数.(n<=10) 后面m行每行两个整数a b.表示从a到b有一条有向边. 输出 若给定有向图存在合法拓扑序列,则输出YES.否则输出NO. 演示样例输入 1 0 2 2 1 2 2 1 演示样例输出 YES

拓扑序列以及排序

一句话题意:求AOV网的拓扑序列,输出按字典序最小的一个. 拓扑排序 : 由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止. (1) 选择一个入度为0的顶点并输出之: (2) 从网中删除此顶点及所有出边. 循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列. (摘自 : 百度百科) 方案一,用邻接矩阵来储存图,时间复杂度为 O(n * n),因为代码简单就不贴出来了. 方案二,用优先队列以及前向星来储存时间