【BFS && 树】UVALive - 7460 Maximum Cut Order

Problem Description

给你T,代表有T组测试数据,每组测试数据给你三个数n,s,m,n代表有n个结点1-n。s代表输出的起始点。m:代表两点之间的边权等于两点的编号相减的绝对值对m取模。让你输出序列,以s开始的序列。该序列满足距离现有的点,最大的边权点进来,如果边权一样,编号最小的点进来。

思路:

建边,因为1-n个点,而且是完全二叉树的结构。我们可以根据root的儿子是root<<1 || root<<1|1来建边。跑一遍dfs就可以把边建好了。然后用优先队列bfs,就可以直接处理上述问题。

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int to, w, next;
    bool operator < (const node &b) const {
        if(w == b.w) return to > b.to;
        else return w < b.w;
    }
};
#define lson root<<1
#define rson root<<1|1
node Map[1000055];
int cnt, head[500055], n, m, s, vis[500055];
void add(int u, int v, int w, int &cnt)//前向星存边
{
    Map[cnt].to = v;
    Map[cnt].w = w;
    Map[cnt].next = head[u];
    head[u] = cnt++;
}
void dfs(int root)
{
    if((lson) <= n)//满足要求,建立双向边
    {
        add(root, lson, ((lson) - root) % m, cnt);
        add(lson, root, ((lson) - root) % m, cnt);
    }
    else return;
    if((rson) <= n)//满足要求,建立双向边
    {
        add(root, rson, ((rson) - root) % m, cnt);
        add(rson, root, ((rson) - root) % m, cnt);
    }
    else return;
    dfs(lson);
    dfs(rson);
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d", &n, &s, &m);
        memset(head, -1, sizeof(head));
        int root = 1;
        cnt = 0;
        dfs(root);//建边
        priority_queue<node> q;//优先出来权值大的,否则出来编号小的
        q.push((node){s, 0});
        memset(vis, 0, sizeof(vis));
        vector<int> ans;
        while(!q.empty())//bfs
        {
            node t = q.top(); q.pop();
            vis[t.to] = 1;
            ans.push_back(t.to);//记录路径
            for(int i = head[t.to]; ~i; i = Map[i].next)
            {
                int to = Map[i].to, w = Map[i].w;
                if(!vis[to])
                {
                    q.push((node){to, w});
                }
            }
        }
        for(int i = 0; i < ans.size(); i++)//输出路径
        {
            if(i) printf(" ");
            printf("%d", ans[i]);
        }
        printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用C++语言改变这个代码的排版,所呈现的效果不变 #include <stdio.h> #include <vector> #include <queue> #include <string> using namespace std; vector<vector<char> >board; int m; int n; struct Position { int x; int y; Position(int x1,int y1): x(x1),y(y1){} }; void dispboard() {for(int i=0;i<m;i++) {printf(" "); for(int j=0;j<n;j++) printf("%c",board[i][j]); printf("\n"); } } void BFS(int i,int j,int m,int n) {queue<Position *>qu; Position * pos=new Position(i,j); qu.push(pos); board[i][j]='*'; while(!qu.empty()) {Position * curp=qu.front(); qu.pop(); if (curp->x>0 && board[curp->x-1][curp->y]=='O') {Position * up=new Position(curp->x-1,curp->y); qu.push(up); board[up->x][up->y]='*'; } if(curp->x<m-1 && board[curp->x+1][curp->y]=='O') {Position * down=new Position(curp->x+1,curp->y); qu.push(down); board[down->x][down->y]='*'; } if(curp->y>0 && board[curp->x][curp->y-1]=='O') {Position * left=new Position(curp->x,curp->y-1); qu.push(left); board[left->x][left->y]='*'; } if(curp->y<n-1 && board[curp->x][curp->y+1]=='O') {Position * right=new Position(curp->x,curp->y+1); qu.push(right); board[right->x][right->y]='*'; } delete curp; } } void solve() { int i,j; for(i=0;i<m;i++) for(j=0;j<n;j++) if(board[i][j]=='O') { if(i==0 || i==m-1 || j==0 || j==n-1) BFS(i,j,m,n); } printf("BFS后的面板:\n");dispboard(); for(i=0;i<m;i++) for(j=0;j<n;j++) { if(board[i][j]=='O') board[i][j]='X'; else if(board[i][j]=='*') board[i][j]='O'; } } void main() {string str[]={"XXXX","XOOX","XXOX","XOXX"}; m=4;n=4; for (int i=0;i<m;i++) {vector<char>s; for (int j=0;j<n;j++) s.push_back(str[i][j]); board.push_back(s); } printf("原始面板:\n"); dispboard(); solve(); printf("最后面板:\n"); dispboard(); }
06-09
#include <stdio.h> #include <vector> #include <queue> #include <string> using namespace std; vector<vector<char>> board; int m; int n; struct Position { int x; int y; Position(int x1, int y1) : x(x1), y(y1) {} }; void dispboard() { for (int i = 0; i < m; i++) { printf(" "); for (int j = 0; j < n; j++) { printf("%c", board[i][j]); } printf("\n"); } } void BFS(int i, int j, int m, int n) { queue<Position*> qu; Position* pos = new Position(i, j); qu.push(pos); board[i][j] = '*'; while (!qu.empty()) { Position* curp = qu.front(); qu.pop(); if (curp->x > 0 && board[curp->x - 1][curp->y] == 'O') { Position* up = new Position(curp->x - 1, curp->y); qu.push(up); board[up->x][up->y] = '*'; } if (curp->x < m - 1 && board[curp->x + 1][curp->y] == 'O') { Position* down = new Position(curp->x + 1, curp->y); qu.push(down); board[down->x][down->y] = '*'; } if (curp->y > 0 && board[curp->x][curp->y - 1] == 'O') { Position* left = new Position(curp->x, curp->y - 1); qu.push(left); board[left->x][left->y] = '*'; } if (curp->y < n - 1 && board[curp->x][curp->y + 1] == 'O') { Position* right = new Position(curp->x, curp->y + 1); qu.push(right); board[right->x][right->y] = '*'; } delete curp; } } void solve() { int i, j; for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { if (board[i][j] == 'O') { if (i == 0 || i == m - 1 || j == 0 || j == n - 1) BFS(i, j, m, n); } } } printf("BFS后的面板:\n"); dispboard(); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { if (board[i][j] == 'O') board[i][j] = 'X'; else if (board[i][j] == '*') board[i][j] = 'O'; } } } int main() { string str[] = { "XXXX","XOOX","XXOX","XOXX" }; m = 4; n = 4; for (int i = 0; i < m; i++) { vector<char> s; for (int j = 0; j < n; j++) { s.push_back(str[i][j]); } board.push_back(s); } printf("原始面板:\n"); dispboard(); solve(); printf("最后面板:\n"); dispboard(); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值