Tree2cycle

Problem Description
A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 unit of cost respectively. The nodes are labeled from 1 to N. Your job is to transform the tree to a cycle(without superfluous edges) using minimal cost.

A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.
 
Input
The first line contains the number of test cases T( T<=10 ). Following lines are the scenarios of each test case.
In the first line of each test case, there is a single integer N( 3<=N<=1000000 ) - the number of nodes in the tree. The following N-1 lines describe the N-1 edges of the tree. Each line has a pair of integer U, V ( 1<=U,V<=N ), describing a bidirectional edge (U, V).
 
Output
For each test case, please output one integer representing minimal cost to transform the tree to a cycle.
 
Sample Input
1 4 1 2 2 3 2 4
 
Sample Output
3
Hint
In the sample above, you can disconnect (2,4) and then connect (1, 4) and (3, 4), and the total cost is 3.
 
Source
#include <stdio.h>
#include <string.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define Maxn 1010000

struct Edge
{
    int v;
    struct Edge *next;
}*head[Maxn<<1],edge[Maxn<<1];

int n,cnt,ans;
void add(int a,int b)
{
    edge[++cnt].v=b,edge[cnt].next=head[a];
    head[a]=&edge[cnt];
}

int dfs(int cur,int pa) //返回分支个数
{
    int res=0;
    struct Edge * p=head[cur];

    while(p)
    {
        if(p->v!=pa) res+=dfs(p->v,cur);
        p=p->next;
    }
    if(res>=2) //超过两个分支,将其它分支链过来
    {
        if(cur==1) ans+=res-2; //树根不用链到其它地方
        else ans+=res-1; //选两个,其它的边都要断开和重新链接一次
        return 0; //断开了
    }
    else return 1; //作为一个单支
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        cnt=0;
        memset(head,NULL,sizeof(head));
        for(int i=1;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        ans=0;
        dfs(1,0);
        printf("%d\n",ans*2+1);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/contestant/p/3311180.html

`timescale 1ns / 1ps module adv_matrix_multiplier #( parameter MAX_SIZE = 8, // Maximum matrix dimension parameter MAX_PARALLEL = 8 // Maximum parallel multipliers )( input clk, input rst_n, input start, input [7:0] M, // Rows of A input [7:0] N, // Columns of A / Rows of B input [7:0] P, // Columns of B input [31:0] A [0:MAX_SIZE-1], input [31:0] B [0:MAX_SIZE-1], input [2:0] mode, // Computation mode output reg done, output reg overflow, output reg [31:0] C [0:MAX_SIZE-1] ); // State definitions with explicit 2-cycle delays typedef enum { IDLE, INIT_ROW, INIT_COL, LOAD_DATA, MULTIPLY_CYCLE1, MULTIPLY_CYCLE2, ADD_TREE_CYCLE1, ADD_TREE_CYCLE2, ACCUMULATE_CYCLE1, ACCUMULATE_CYCLE2, STORE_RESULT, CHECK_COLUMN, CHECK_ROW, FINISH } state_t; // Control registers reg [7:0] row_idx, col_idx, inner_idx; reg [7:0] M_reg, N_reg, P_reg; reg [7:0] parallel_factor; state_t current_state, next_state; // Data path registers reg [31:0] accumulator; reg global_overflow; // Multiplier array (2-cycle latency) reg [31:0] a_in [0:MAX_PARALLEL-1]; reg [31:0] b_in [0:MAX_PARALLEL-1]; wire [63:0] product [0:MAX_PARALLEL-1]; wire mul_overflow [0:MAX_PARALLEL-1]; // Adder tree (2-cycle latency) reg [31:0] adder_input [0:MAX_PARALLEL-1]; reg [31:0] adder_stage1 [0:MAX_PARALLEL-1]; // Pipeline register wire [32:0] adder_output [0:MAX_PARALLEL/2-1]; wire adder_overflow [0:MAX_PARALLEL/2-1]; // Accumulator adder (2-cycle latency) reg [31:0] acc_input_a, acc_input_b; reg [31:0] acc_stage1; // Pipeline register wire [32:0] acc_result; wire acc_overflow; // Pipeline control registers reg [31:0] partial_sum; reg partial_sum_overflow; reg [7:0] next_inner_idx; reg [7:0] saved_row, saved_col; // Index calculation wire [7:0] a_index = row_idx * N_reg + inner_idx; wire [7:0] b_index = inner_idx * P_reg + col_idx; wire [7:0] c_index = row_idx * P_reg + col_idx; // Parallel factor calculation always @(*) begin if (N_reg <= 2) parallel_factor = 1; else if (N_reg <= 4) parallel_factor = 2; else if (N_reg <= 8) parallel_factor = 4; else parallel_factor = MAX_PARALLEL; end // Multiplier instances generate for (genvar i = 0; i < MAX_PARALLEL; i++) begin : gen_mult mul multiplier ( .clk(clk), .rst_n(rst_n), .a_in(a_in[i]), .b_in(b_in[i]), .mode(mode), .overflow(mul_overflow[i]), .c(product[i]) ); end endgenerate // Adder tree instances generate for (genvar i = 0; i < MAX_PARALLEL/2; i++) begin : gen_add add adder ( .clk(clk), .rst_n(rst_n), .a_in(adder_stage1[2*i]), .b_in(adder_stage1[2*i+1]), .mode(mode), .overflow(adder_overflow[i]), .s(adder_output[i]) ); end endgenerate // Accumulator adder add accum_adder ( .clk(clk), .rst_n(rst_n), .a_in(acc_input_a), .b_in(acc_stage1), .mode(mode), .overflow(acc_overflow), .s(acc_result) ); // Main state machine always @(posedge clk or negedge rst_n) begin if (!rst_n) begin current_state <= IDLE; done <= 0; overflow <= 0; global_overflow <= 0; accumulator <= 0; row_idx <= 0; col_idx <= 0; inner_idx <= 0; // Clear all pipeline registers for (int i = 0; i < MAX_PARALLEL; i++) begin a_in[i] <= 0; b_in[i] <= 0; adder_input[i] <= 0; adder_stage1[i] <= 0; end acc_input_a <= 0; acc_stage1 <= 0; partial_sum <= 0; end else begin current_state <= next_state; // Default assignments overflow <= global_overflow; case (current_state) IDLE: begin if (start) begin M_reg <= M; N_reg <= N; P_reg <= P; row_idx <= 0; col_idx <= 0; global_overflow <= 0; next_state <= INIT_ROW; end end INIT_ROW: begin inner_idx <= 0; next_state <= INIT_COL; end INIT_COL: begin accumulator <= 0; next_state <= LOAD_DATA; end LOAD_DATA: begin // Load data for parallel processing for (int i = 0; i < parallel_factor; i++) begin if (inner_idx + i < N_reg) begin a_in[i] <= A[a_index + i]; b_in[i] <= B[b_index + i]; end else begin a_in[i] <= 0; b_in[i] <= 0; end end // Save current indices saved_row <= row_idx; saved_col <= col_idx; next_state <= MULTIPLY_CYCLE1; end MULTIPLY_CYCLE1: begin // First cycle of multiplication next_state <= MULTIPLY_CYCLE2; end MULTIPLY_CYCLE2: begin // Second cycle - multiplication results ready // Check for multiplier overflows for (int i = 0; i < parallel_factor; i++) begin if (mul_overflow[i]) global_overflow <= 1; adder_input[i] <= product[i][31:0]; end next_state <= ADD_TREE_CYCLE1; end ADD_TREE_CYCLE1: begin // First cycle of addition tree for (int i = 0; i < parallel_factor; i++) begin adder_stage1[i] <= adder_input[i]; end next_state <= ADD_TREE_CYCLE2; end ADD_TREE_CYCLE2: begin // Second cycle - addition results ready automatic int active_adders = (parallel_factor + 1) / 2; automatic logic [31:0] sum = 0; automatic logic ovf = 0; // Process adder tree outputs for (int i = 0; i < active_adders; i++) begin sum += adder_output[i][31:0]; ovf |= adder_overflow[i] | adder_output[i][32]; end // Handle odd number of elements if (parallel_factor % 2 == 1) begin automatic logic [32:0] temp = {1'b0, sum} + {1'b0, adder_stage1[parallel_factor-1]}; sum = temp[31:0]; ovf |= temp[32]; end partial_sum <= sum; partial_sum_overflow <= ovf; next_inner_idx <= inner_idx + parallel_factor; next_state <= ACCUMULATE_CYCLE1; end ACCUMULATE_CYCLE1: begin // First cycle of accumulation acc_input_a <= accumulator; acc_stage1 <= partial_sum; if (partial_sum_overflow) global_overflow <= 1; next_state <= ACCUMULATE_CYCLE2; end ACCUMULATE_CYCLE2: begin // Second cycle - accumulation result ready accumulator <= acc_result[31:0]; if (acc_overflow | acc_result[32]) global_overflow <= 1; inner_idx <= next_inner_idx; if (next_inner_idx >= N_reg) begin next_state <= STORE_RESULT; end else begin next_state <= LOAD_DATA; end end STORE_RESULT: begin C[c_index] <= accumulator; next_state <= CHECK_COLUMN; end CHECK_COLUMN: begin if (col_idx == P_reg - 1) begin next_state <= CHECK_ROW; end else begin col_idx <= col_idx + 1; next_state <= INIT_ROW; end end CHECK_ROW: begin if (row_idx == M_reg - 1) begin next_state <= FINISH; end else begin row_idx <= row_idx + 1; col_idx <= 0; next_state <= INIT_ROW; end end FINISH: begin done <= 1; if (start) begin done <= 0; next_state <= IDLE; end end endcase end end endmodule
最新发布
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值