保研机试 图论问题总结

一、拓扑排序

1、Genealogical tree POJ - 2367

题意:

给出N个点,然后给出N行数据,0结束,代表第I行的儿子是哪几个。求出最后的拓扑序列。

思路:

直接根据拓扑排序,先把度数为0的i点放入队列,然后更新i点的指向度的度数。利用容器存储队列每次出了时答案。

代码:

#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include
#include
#include
#include
#include
#include 
using namespace std;
const int maxn=100+10;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
queueq;
int du[maxn];
int n;
vectorans;
vectoredge[maxn];
void topo()
{
    while(q.size())
    {
        int x=q.front();
        q.pop();
        ans.push_back(x);
        for(int i=0;i>n;
    rep(i,1,n)
    {
        int x;
        while(cin>>x)
        {
            if(!x)break;
            du[x]++;
            edge[i].push_back(x);
        }
    }
    rep(i,1,n)
    {
        if(!du[i])
        {
            q.push(i);//第i个点
        }
    }
    topo();
    for(int i=0;i

2、逃生 HDU - 4857 

思路:

这个题需要反向建图,因为他并不是输出字典序最小,而是让1、2、3依次的尽量小,

例如 1->4->2和5->3->2。

正向建图结果是1 4 5 3 2,可是正确的结果应该是1 5 3 4 2,因为满足了1尽量小之后要满足2,满足了2之后满足3.....

代码:

#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include
#include
#include
#include
#include
#include 
#include
using namespace std;
const int maxn=100000+10;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
priority_queueq;
int du[maxn];
int n,m;
vectoredge[maxn];
stackans;
void topo()
{
    while(q.size())
    {
        int x=q.top();
        q.pop();
        ans.push(x);
        for(int i=0; i1)
        {
            printf("%d ",ans.top());
            ans.pop();
        }
        printf("%d\n",ans.top());
        ans.pop();
    }
    return 0;
}

3、Following Orders POJ - 1270

题意:

第一行给出字母,第二行给出字母对(x,y),代表x

思路:

dfs+回溯

枚举所有可能的情况输出。

代码:

#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include
#include
#include
#include
#include
#include 
#include
using namespace std;
const int maxn=30+10;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
bool vis[maxn];
char ch[maxn];
int cnt;
int du[maxn];
bool visi[maxn][maxn];
char ans[maxn];
char str[maxn];
mapmmp;
void dfs(int x)
{
    //cout<cnt+1)
        return ;
    if(x==cnt+1)
    {
        rep(i,1,cnt)
        {
            cout<

4、Frame Stacking POJ - 1128

题意:

一个图片里只有一种字母,现在给出几个图片覆盖形成的图片,例如A图片里面某位置有'A',B在它上面,那么'B’就覆盖了'A'。

现在让求出所有可能的覆盖方式。

思路:

枚举每一个字母矩形(记录其左上角和右下角的点)的边上的点有哪些,这些边上的点一定是覆盖该字母的图片,建图,然后拓扑排序+回溯求出所有可能。

代码:

#include
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include
#include
#include
#include
#include
#include 
using namespace std;
const int maxn=30+10;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
int n,m;
struct node
{
    int lx,ly,rx,ry;
} pos[maxn];
char ch[maxn][maxn];
bool vis[maxn];
bool visi[maxn][maxn];
int cnt=0;
char ans[maxn];
int in[maxn];
void dfs(int x)
{
    if(x==cnt+1)
    {
        rep(i,1,cnt)
        cout<

二、最小生成树

1、

你可能感兴趣的:(考研机试)