uva 11748 - Rigging Elections

本文介绍了一种通过操纵候选人间的对决顺序来确保特定候选人获胜的算法。该算法利用投票数据预测不同候选人之间的胜负,并构建有向图来确定是否可以通过合理安排比赛顺序使首选候选人赢得最终的选举。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem G: Rigging Elections

Elections in your country are performed in a one-on-one elimination style. Each week, two people are chosen from a pool of candidates and the country votes on which one they prefer. The loser is eliminated and the winner is returned to the pool of candidates. This process continues until only one candidate remains.

To make a bad voting system even worse, a single person is charged with the responsibility of choosing the two candidates each week. This person happens to be you! Since you are a very selfish person, you plan on rigging the election so your preferred candidate wins. You have access to polling data from which you can determine who would win in every possible head-to-head matchup. Assuming the data accurately represents what the real outcome would be, is it possible to schedule the candidates so your candidate wins?

Input Format

The first line of each test case contains three integers n, m, and c with 1 ≤ n ≤ 100, 1 ≤ m ≤ 100 and 1 ≤ c ≤ n. Here, n indicates the total number of candidates in the initial pool, m is the number of voters and c is the number of your preferred candidate. This is followed by m lines, each containing a permutation of the numbers 1 through n. The i'th line should be interpreted as a ranking of the n candidates by voter i. If two candidates are pitted against each other in an election, then voter i will vote for whoever appears first in their list. You may also assume m is always odd. The last line of input contains three zeros and should not be processed.

Output Format

There is a single line of output for each test case with either the message yes or no indicating if it is possible for you to rig the elections so your preferred candidate c wins.

Sample Input

3 3 1
1 2 3
2 3 1
3 1 2
3 3 1
1 2 3
2 3 1
3 2 1
0 0 0

Sample Output

yes
no

Zac Friggstad


n、m很小,可以先处理出任意两个人做比较,谁赢。如果x赢y,则x连一条有向边到y,然后判断从c能否到达图中所有的点,可以的话,yes,否则no。

#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
#include <stdlib.h>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100 + 5;

int Rank[maxn][maxn];
vector<int> G[maxn];
int cnt;
int vis[maxn];

void dfs(int x){
    vis[x] = 1;
    cnt++;
    for(int i = 0;i < G[x].size();i++){
        int to = G[x][i];
        if(vis[to] == 0)
            dfs(to);
    }
}

int main(){
    int n, m, c;
    while(scanf("%d%d%d", &n, &m, &c)){
        if(n == 0 && m == 0 && c == 0) break;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                int x;scanf("%d", &x);
                Rank[i][x] = j;
            }
        }
        for(int i = 0;i < maxn;i++) G[i].clear();
        for(int i = 1;i <= n;i++){
            for(int j = i+1;j <= n;j++){
                int cnti = 0, cntj = 0;
                for(int k = 0;k < m;k++){
                    if(Rank[k][i] < Rank[k][j])
                        cnti++;
                    else
                        cntj++;
                }
                if(cnti > cntj)
                    G[i].push_back(j);
                else
                    G[j].push_back(i);
            }
        }

        memset(vis, 0, sizeof(vis));
        cnt = 0;
        dfs(c);
        if(cnt == n)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值