P3243 [HNOI2015] Gerichte kochen (Denken + topologisches Sortieren + Umkehrgraphik)

Themenbeschreibung
Ein bekannter Feinschmecker wird ins ATM Hotel eingeladen, um für ihn Gerichte zu bewerten. Das ATM-Hotel hat nn Gerichte für Herrn A. zubereitet. Das Hotel vergibt Nummern von 11 bis nn entsprechend der geschätzten Qualität der Gerichte, und die Anzahl der Gerichte mit der höchsten geschätzten Qualität beträgt 11.

Aufgrund des Problems der Geschmacksübereinstimmung zwischen Gerichten müssen einige Gerichte vor anderen Gerichten zubereitet werden. Insbesondere gibt es m Einschränkungen, so dass Gericht i vor Gericht jj zubereitet werden muss. Wir kürzen solche Einschränkungen als (i,j)(i,j) ab ).

Nun hofft das Hotel, eine optimale Reihenfolge der Kochgerichte zu finden, damit Little A zuerst versuchen kann, hochwertige Gerichte zu essen:

Das heißt,

Unter der Prämisse, alle Einschränkungen zu erfüllen, sollte Gericht Nr. 1 möglichst zuerst zubereitet werden.

Unter der Voraussetzung, dass alle Einschränkungen erfüllt sind und Gericht Nr. 1 so weit wie möglich zubereitet wird, wird Gericht Nr. 2 so weit wie möglich zubereitet.

Unter der Voraussetzung, dass alle Randbedingungen erfüllt sind und die Gerichte Nr. 1 und Nr. 2 möglichst priorisiert werden, sollte Gericht Nr. 3 so oft wie möglich zubereitet werden.

Unter der Voraussetzung, dass alle Einschränkungen erfüllt sind und die Gerichte Nr. 1, Nr. 2 und Nr. 3 so weit wie möglich priorisiert werden, sollte Gericht Nr. 4 so oft wie möglich zubereitet werden.

und so weiter.

Beispiel 1: Insgesamt 4 Gerichte, zwei Restriktionen (3,1), (4,1), dann ist die Produktionsreihenfolge 3,4,1,2.

Beispiel 2: Es gibt insgesamt 5 Gerichte, zwei Restriktionen (5,2), (4,3), dann ist die Produktionsreihenfolge 1,5,2,4,3.

Betrachten Sie in Beispiel 1 zuerst 1, da es Einschränkungen (3,1) und (4,1) gibt, sodass 1 erst erstellt werden kann, nachdem 3 und 4 erstellt wurden, und entsprechend der Nummer 3 sollte ihr Vorrang eingeräumt werden 44, also ist es derzeit möglich Bestimmen Sie, dass die Produktionsreihenfolge der ersten drei Gerichte 3,4,13,4,1 ist. Betrachten Sie dann 22 und bestimmen Sie, dass die endgültige Produktionsreihenfolge 3,4,1,23,4 ist. 1,2.

In Beispiel 2 verstößt es nicht gegen die Einschränkung, zuerst 1 zu machen; dann gibt es eine Einschränkung von (5,2), wenn man 2 betrachtet, also macht man zuerst 5 und dann 2; als nächstes, wenn man 33 betrachtet, gibt es (4, 3)(4 ,3), also zuerst 44 und dann 33, also ist die endgültige Sequenz 1,5,2,4,31,5,2,4,3. Jetzt müssen Sie die optimale Reihenfolge für die Zubereitung von Gerichten herausfinden. Keine Lösungsausgabe Unmöglich! (Der erste Buchstabe wird groß geschrieben, die restlichen Buchstaben sind Kleinbuchstaben)

Eingabeformat
Die erste Zeile ist eine positive Ganzzahl t, die die Anzahl der Datensätze angibt. Als nächstes folgt die t-Datengruppe. Für jeden Datensatz: Die erste Zeile enthält zwei durch Leerzeichen getrennte positive ganze Zahlen n und mm, die jeweils die Anzahl der Gerichte und die Anzahl der durch die Produktionsreihenfolge begrenzten Einträge darstellen. Die nächste mm-Zeile enthält jeweils zwei positive ganze Zahlen x, yx, y, was die Einschränkung angibt, dass Gericht xx vor Gericht yy zubereitet werden muss.

Ausgabeformat
Die Ausgabedatei enthält nur t Zeilen, jede Zeile enthält n ganze Zahlen, was die optimale Kochsequenz bedeutet, oder Unmöglich! bedeutet keine Lösung.

Eingabe Ausgabebeispiel
Eingabe Nr. 1 Kopie
3
5 4 5
4 5
3 4 2 3 2 3 3 1 2 2 3 3 1 5 2 5 2 4 3 Ausgabe Nr. 1 Kopie 1 5 3 4 2  Unmöglich!  1 5 2 4 3












Analysieren:

Die optimale Reihenfolge ist nicht die kleinste lexikografische Reihenfolge. Es gibt noch ein drittes Beispiel, das Sie kennen sollten.

Wenn zur Aufrechterhaltung der Topologie ein kleiner Root-Heap verwendet wird, funktioniert dies offensichtlich nicht, da auf diese Weise die topologische Reihenfolge mit der kleinsten lexikografischen Reihenfolge erhalten wird und 1 nicht unbedingt an erster Stelle stehen sollte.

Da die lexikografische Reihenfolge gierig ist, sollte die vorherige so klein wie möglich sein, wenn sie klein sein kann, und es gibt keine Garantie dafür, dass 1 so früh wie möglich erscheint.

Aber wenn Sie einen inversen Graphen erstellen und eine topologische Ordnung mit der größten umgekehrten lexikografischen Ordnung finden

Dann wird es eine Situation geben, in der die große Zahl so nah wie möglich vorne liegt, die kleine Zahl also so nah wie möglich hinten und die kleine Zahl wiederum so nah wie möglich vorne.

Erstellen Sie die Karte also einfach in umgekehrter Reihenfolge + einen großen Root-Heap für die Wartung

#include<bits/stdc++.h>
using namespace std;
const int MAX = 100010;
struct edge {
    int v, next;
}e[MAX];
int d, n, m, in[MAX], cnt, head[MAX], a[MAX];
priority_queue<int> q; //默认大根堆
inline int read() {
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c>'9') {
        if (c == '-') {
            f = -1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + c - '0';
        c = getchar();
    }
    return x * f;
}
void add(int u, int v) {
    e[++cnt].v = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}
int bfs() {
    while (!q.empty()) {
        int p = q.top();
        q.pop();
        cnt++;
        a[cnt] = p;
        for (int i = head[p]; i > 0; i = e[i].next) {
            int v = e[i].v;
            in[v]--;
            if (!in[v]) {
                q.push(v);
            }
        }
    }
    return cnt == n;//没有环
}
int main() {
    d = read();
    while (d--) {
        memset(in, 0, sizeof(in));
        memset(head, 0, sizeof(head));
        cnt = 0;
        n = read(), m = read();
        for (int i = 1; i <= m; i++) {
            int x, y;
            x = read(), y = read();
            add(y, x); // 反向边
            in[x]++;
        }
        for (int i = 1; i <= n; i++) {
            if (!in[i]) {
                q.push(i);
            }
        }
        cnt = 0;
        if (bfs()) {
            for (int i = n; i >= 1; i--) {
                printf("%d ", a[i]);
            }
            printf("\n");
        }
        else {
            printf("Impossible!\n");
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/129648937