zoukankan      html  css  js  c++  java
  • 【LOJ】#2114. 「HNOI2015」菜肴制作

    题解

    把所有边反向
    从小到大枚举每个点,把每个点能到达的点挑出来,判完无解后显然是一个DAG,然后在上面求一个编号最大的拓扑序,把这些点全部标记为已选,把每次求得的拓扑序倒序输出

    代码

    
    
    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef long double db;
    typedef unsigned int u32;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {putchar('-');x = -x;}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    struct node {
        int to,next;
    }E[MAXN * 2];
    int D,head[MAXN],sumE,N,M,ind[MAXN],L[MAXN],cnt,tims,vis[MAXN];
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    bool dfs(int u) {
        vis[u] = 1;
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(vis[v] == 1) return false;
    	if(!vis[v]) {if(!dfs(v)) return false;}
        }
        vis[u] = 2;
        return true;
    }
    void dfs1(int u) {
        vis[u] = tims;
        for(int i = head[u]; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(!vis[v]) dfs1(v);
        }
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(vis[v] == tims) ++ind[v];
        }
    }
    priority_queue<int> Q;
    void BFS(int st) {
        Q.push(st);
        cnt = 0;
        while(!Q.empty()) {
    	int u = Q.top();Q.pop();
    	L[++cnt] = u;
    	for(int i = head[u] ; i ; i = E[i].next) {
    	    int v = E[i].to;
    	    if(vis[v] == tims) {
    		--ind[v];
    		if(ind[v] == 0) Q.push(v);
    	    }
    	}
        }
    }
    void Solve() {
        read(N);read(M);
        memset(ind,0,sizeof(ind));
        memset(vis,0,sizeof(vis));
        sumE = 0;memset(head,0,sizeof(head));
        int u,v;
        for(int i = 1 ; i <= M ; ++i) {
    	read(u);read(v);
    	add(v,u);
        }
        for(int i = 1 ; i <= N ; ++i) {
    	if(!vis[i] && !dfs(i)) {
    	    puts("Impossible!");
    	    return;
    	}
        }
        memset(vis,0,sizeof(vis));
        for(int i = 1 ; i <= N ; ++i) {
    	if(!vis[i]) {
    	    ++tims;
    	    dfs1(i);
    	    BFS(i);
    	    for(int j = cnt ; j >= 1 ; --j) {
    		out(L[j]);space;
    	    }
    	}
        }
        enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        read(D);
        while(D--) {
    	Solve();	
        }
    }
    
  • 相关阅读:
    外校培训前三节课知识集合纲要(我才不会告诉你我前两节只是单纯的忘了)
    floyd算法----牛栏
    bfs开始--马的遍历
    (DP 线性DP 递推) leetcode 64. Minimum Path Sum
    (DP 线性DP 递推) leetcode 63. Unique Paths II
    (DP 线性DP 递推) leetcode 62. Unique Paths
    (DP 背包) leetcode 198. House Robber
    (贪心 复习) leetcode 1007. Minimum Domino Rotations For Equal Row
    (贪心) leetcode 452. Minimum Number of Arrows to Burst Balloons
    (字符串 栈) leetcode 921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9641443.html
Copyright © 2011-2022 走看看