codeforces1608C. Game Master Problem Solution (Graph Theory)

The meaning of the question is to give you n players, each player has two strengths a and b, and then conduct n-1 rounds of eliminations. Those with smaller strengths (using the same strength) will withdraw from the game. Finally, you will be asked whether each player can win the game.

(Can’t read the solution)

If player A can defeat player B, and player B can defeat player C, then player A can indirectly eliminate player C. There is a transitive relationship here.

We sort all the players in order of strength a and b from small to large. Starting from the node of the player with greater strength, we connect an edge to the player with smaller strength. We just need to see if any node can traverse all nodes.

But the time complexity of doing this is n2. We can think of it. If a player wants to win, he must defeat (indirectly or directly) the player with the highest strength, and the player with the highest strength can defeat all other players, so as long as a player can reach the highest strength The player’s node wins

Therefore, we establish anti-edges for all edges. As long as the node of the player with the strongest strength can reach it, it is the node of the player who can win.

The AC code is as follows

#include <bits/stdc++.h>
using namespace std;

int ne[200010],v[200010],ha[200010];
int idx;
bool ans[100010];//答案
void add(int a,int b)
{
	idx++;
	v[idx]=b;
	ne[idx]=ha[a];
	ha[a]=idx;
}//建图
struct pii
{
	int w,id;
};

bool cmp(pii &a,pii &b)
{
	return a.w<b.w;
}

void dfs(int x,int fa)
{
	ans[x]=true;
	for(int i=ha[x];i;i=ne[i])
	{
		int k=v[i];
		if(k==fa || ans[k]) continue;
		dfs(k,x);
	}
}
int main(){
	int t;
	cin>>t;
	while(t--)
	{
		idx=0;
        int n;
        cin>>n;
        
        for(int i=1;i<=2*n;i++)
        ne[i]=v[i]=ha[i]=0;
	    
        vector<pii> a(n),b(n);
        for(int i=0;i<n;i++)
        {
        	ans[i+1]=false;
        	cin>>a[i].w;
        	a[i].id=i+1;
		}
        for(int i=0;i<n;i++)
        {
            cin>>b[i].w;
            b[i].id=i+1;
        }

        sort(a.begin(),a.end(),cmp);
        sort(b.begin(),b.end(),cmp);
        
        for(int i=0;i<n-1;i++)
        {
        	add(a[i].id,a[i+1].id);
        	add(b[i].id,b[i+1].id);//连反边
		}
		
        dfs(a[n-1].id,-1);//从a力量最大的结点开始dfs
        
        for(int i=1;i<=n;i++)
        if(ans[i]) cout<<1;
        else cout<<0;
        
        cout<<"\n";
        
        
	}
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_30798083/article/details/123714086