特殊图poj2367-Genealogical tree poj-1776Task Sequences BZOJ1006: [HNOI2008]神奇的国度

特殊图poj2367-Genealogical tree poj-1776Task Sequences BZOJ1006: [HNOI2008]神奇的国度

分类:
树:无环联通图
平面图:边没交点
平面图的对偶图:平面图网络流转化为最短路
有向无环图
二分图
正则图:任意俩顶点度数相同
弦图:图中任意长度大于3的环都含一条弦
竞赛图:任意两点间有切仅有一条有向边


算法:
拓扑排序
O(V+E)

Genealogical tree
Time Limit: 1000MS
Memory Limit: 65536K
Special Judge
Description
The system of Martians’ blood relations is confusing enough. Actually, Martians bud when they want and where they want. They gather together in different groups, so that a Martian can have one parent as well as ten. Nobody will be surprised by a hundred of children. Martians have got used to this and their style of life seems to them natural.
And in the Planetary Council the confusing genealogical system leads to some embarrassment. There meet the worthiest of Martians, and therefore in order to offend nobody in all of the discussions it is used first to give the floor to the old Martians, than to the younger ones and only than to the most young childless assessors. However, the maintenance of this order really is not a trivial task. Not always Martian knows all of his parents (and there’s nothing to tell about his grandparents!). But if by a mistake first speak a grandson and only than his young appearing great-grandfather, this is a real scandal.
Your task is to write a program, which would define once and for all, an order that would guarantee that every member of the Council takes the floor earlier than each of his descendants.
Input
The first line of the standard input contains an only number N, 1 <= N <= 100 — a number of members of the Martian Planetary Council. According to the centuries-old tradition members of the Council are enumerated with the natural numbers from 1 up to N. Further, there are exactly N lines, moreover, the I-th line contains a list of I-th member’s children. The list of children is a sequence of serial numbers of children in a arbitrary order separated by spaces. The list of children may be empty. The list (even if it is empty) ends with 0.
Output
The standard output should contain in its only line a sequence of speakers’ numbers, separated by spaces. If several sequences satisfy the conditions of the problem, you are to write to the standard output any of them. At least one such sequence always exists.
Sample Input
5
0
4 5 1 0
1 0
5 3 0
3 0
Sample Output
2 4 5 3 1
Source
Ural State University Internal Contest Octobe2000 Junior Session

题意:输出一个拓扑序
流程:
(1)入度0的点入队
(2)每次取出队首的点
(3)连出的边入度-1,重复(1)
(4)重复(2)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 200;

int n, map[MAXN][MAXN], in[MAXN];
queue<int> q;

void BFS(){
    for (int i = 1; i <= n; ++i)
      if (!in[i])
        q.push(i);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      cout<<x<<" ";
      for (int i = 1; i <= n; ++i) {
        if (!map[x][i]) continue;
        in[i]--;
        if (!in[i])
          q.push(i);
      }
    }
}

int main()
{
    freopen("in.txt", "r", stdin);
    cin>>n;
    for (int i = 1; i <= n; ++i) {
      int x; cin>>x;
      while (x) {
        map[i][x] = 1;
        in[x]++;
        cin>>x;
      }
    }
    BFS();
    return 0;
} 

Task Sequences
Time Limit: 1000MS
Memory Limit: 65536K
Special Judge
Description
Tom has received a lot of tasks from his boss, which are boring to deal with by hand. Fortunately,Tom got a special machine - Advanced Computing Machine (ACM) to help him.
ACM works in a really special way. The machine can finish one task in a short time, after it’s finishing one task, it should smoothly move to the next one, otherwise the machine will stop automatically. You must start it up again to make it continue working. Of course, the machine cannot move arbitrarily from one task to another. So each time before it starts up, one task sequence should be well scheduled. Specially, a single task also can be regarded as a sequence. In the sequence, the machine should be able to smoothly move from one task to its successor (if exists). After started up, the machine always works according to the task sequence, and stops automatically when it finishes the last one. If not all the tasks have been finished, the machine has to start up again and works according to a new sequence. Of course, the finished tasks can’t be scheduled again.
For some unknown reasons, it was guaranteed that for any two tasks i and j, the machine can smoothly move from i to j or from j to i or both. Because the startup process is quite slow, Tom would like to schedule the task sequences properly, so that all the tasks can be completed with minimal number of startup times. It is your task to help him achieve this goal.
Input
Input contains several testcases. For each testcase, the first line contains only one integer n, (0 < n <= 1,000), representing the number of tasks Tom has received. Then n lines follow. Each line contains n integers, 0 or 1, separated by white spaces. If the jth integer in the ith line is 1, then the machine can smoothly move from task i to task j, otherwise the machine can not smoothly move from task i to task j. The tasks are numbered from 1 to n.
Input is terminated by end of file.
Output
For each testcase, the first line of output is only one integer k, the minimal number of startup times needed. And 2k lines follow, to describe the k task sequences. For each task sequence, the first line should contain one integer m, representing the number of tasks in the sequence. And the second line should contain m integers, representing the order of the m tasks in the sequence. Two consecutive integers in the same line should be separated by just one white space. Extra spaces are not allowed. There may be several solutions, any appropriate one is accepted.
Sample Input
3
0 1 1
1 0 1
0 0 0
Sample Output
1
3
2 1 3
Source
Asia Guangzhou 2003

找哈密顿回路:
(1)前提:竞赛图一定存在一条哈密顿路
(2)若竞赛图中,点集S = {v1……vi-1}为首尾
相连的边,对vi,一定有一种方法将它加入到S中

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 1000 + 10;

int read(){
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0'||ch>'9') { 
      if (ch == '-') k = -1;
      ch = getchar();
    }
    while ('0'<=ch && ch<='9') {
      x = x * 10 + ch - '0';
      ch = getchar();
    }
    return k * x;
}

int n, num[MAXN], head[MAXN], map[MAXN][MAXN], next[MAXN]; 

void solve(){
    int head = 1;
    num[head] = 1;
    next[head] = -1;
    for (int i = 2; i <= n; ++i) {
      num[i] = i;
      for (int j = head; j != -1; j = next[j]) {    
        if (j == head && map[i][num[j]]) {
          next[i] = head;
          head = i;
          break;
        }
        if (next[j] != -1 && map[num[j]][i] && map[i][num[next[j]]]) {
          next[i] = next[j];
          next[j] = i;
          break;
        }
        if (next[j] == -1) {
          next[i] = next[j];
          next[j] = i;
          break;
        }
      }
    }
    printf("1\n%d\n", n);
    printf("%d", head);
    for (int i = next[head]; i != -1; i = next[i]) {
      printf(" %d", num[i]);
    }
    printf("\n");
}

int main()
{
    freopen("in.txt", "r", stdin);
    while (scanf("%d", &n) != EOF) {
      memset(map, 0, sizeof map);
      for (int i = 1; i <= n; ++i) 
        for (int j = 1; j <= n; ++j)
          map[i][j] = read();;
      solve();
    }
    return 0;
}

1006: [HNOI2008]神奇的国度
Time Limit: 20 Sec Memory Limit: 162 MB
Submit: 3998 Solved: 1851
[Submit][Status][Discuss]
Description
  K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA
相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2
…An之间仅存在N对认识关系:(A1A2)(A2A3)…(AnA1),而没有其它认识关系.比如四边关系指ABCD四个人 AB,BC,C
D,DA相互认识,而AC,BD不认识.全民比赛时,为了防止做弊,规定任意一对相互认识的人不得在一队,国王相知道,
最少可以分多少支队。
Input
  第一行两个整数N,M。1<=N<=10000,1<=M<=1000000.表示有N个人,M对认识关系. 接下来M行每行输入一对朋

Output
  输出一个整数,最少可以分多少队
Sample Input
4 5
1 2
1 4
2 4
2 3
3 4
Sample Output
3
HINT
 一种方案(1,3)(2)(4)
Source

完美消除序列:O(V+E)
流程:
(1)对于每个下标i(从n开始倒序)
(2)Vi = V{V1…Vi-1}与{V1…Vi-1}
中相连最多的点
(3)对{Vi}倒叙贪心获得染色方案
处理的难点在(2)
首先会想到用堆维护,时间复杂度为O((V+E)logV)
实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 10000 + 10;

int read(){
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0'||ch>'9') { 
      if (ch == '-') k = -1;
      ch = getchar();
    }
    while ('0'<=ch && ch<='9') {
      x = x * 10 + ch - '0';
      ch = getchar();
    }
    return k * x;
}

int n, m;
int vis[MAXN], cnt[MAXN], col[MAXN], used[MAXN], res[MAXN];
vector<int> map[MAXN];
//vector<int> bucket[MAXN];

int LCS(){
    priority_queue<pair<int, int> > q;
    for (int i = 1; i <= n; ++i)
      q.push(make_pair(0, i));
    for (int i = n; i >= 1; --i) {
        while (1) {
          int u = q.top().second;
          q.pop();
          if (vis[u]) continue;
          vis[u] = i;
          res[i] = u;
          for (vector<int> :: iterator iter = map[u].begin(); iter != map[u].end(); ++iter)
            if (!vis[*iter])
              q.push(make_pair(++cnt[*iter], *iter));
          break;
        }
    }
    int ans = 1;
    for (int j = n; j >= 1; --j) {
      int iter = res[j], can = 1;
      for (int i = 0; i < map[iter].size(); ++i)
        used[col[map[iter][i]]] = j;
      while (used[can] == j) can++;
      col[iter] = can;
      ans = max(ans, can);
    }   
    return ans;
}

int main()
{
    freopen("in.txt", "r", stdin);
    n = read(), m = read();
    for (int i = 1; i <= m; ++i) {
      int x = read(), y = read();
      map[x].push_back(y);
      map[y].push_back(x);
    }
    printf("%d", LCS());
    return 0;
}

用时1372 ms
看到有神犇180s搞定,于是想有没有别的办法。发现,只需要用个桶排序,与{V1…Vi}连的边数作为桶,维护桶的复杂度低于堆。
实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 10000 + 10;

int read(){
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0'||ch>'9') { if (ch == '-') k = -1; ch = getchar(); }
    while ('0'<=ch && ch<='9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return k * x;
}

int n, m;
int vis[MAXN], cnt[MAXN], col[MAXN], res[MAXN], used[MAXN];
vector<int> map[MAXN];
vector<int> bucket[MAXN];

int get(){
    int top = 0;
    for (int i = 1; i <= n; ++i)
      bucket[0].push_back(i);
    for (int i = n; i >= 1; --i) {
        while (1) {
          //桶维护 
          if (!bucket[top].size()) top--;
          vector<int> :: iterator bri = bucket[top].end() - 1;
          bucket[top].erase(bri);
          int u = *bri;
          //得到完全消除序列的第i个 
          if (vis[u]) continue;
          vis[u] = i;
          res[i] = u;
          //更新不在序列里的结点的cnt值 
          for (vector<int> :: iterator iter = map[u].begin(); iter != map[u].end(); ++iter)
            if (!vis[*iter]) {
              ++cnt[*iter];
              if (cnt[*iter] > top) top = cnt[*iter];
              bucket[cnt[*iter]].push_back(*iter);
            }
          break;
        }
    }
    int ans = 1;
    for (int j = n; j >= 1; --j) {
      int iter = res[j], can = 1;
      for (int i = 0; i < map[iter].size(); ++i)
        used[col[map[iter][i]]] = j;
      while (used[can] == j) can++;
      col[iter] = can;
      ans = max(ans, can);
    }   
    return ans;
}

int main()
{
    freopen("in.txt", "r", stdin);
    n = read(), m = read();
    for (int i = 1; i <= m; ++i) {
      int x = read(), y = read();
      map[x].push_back(y);
      map[y].push_back(x);
    }
    printf("%d", get());
    return 0;
}

用时656 ms。这说明,我离神犇差大约三个神犇的距离。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值