poj3268-Silver Cow Party

(堆)poj3268-Silver Cow Party

先是堆排練練手。
堆排序

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100000;
const int INF = 0x7fffffff;

struct BinaryHeap{
    int heap[MAXN], id[MAXN], pos[MAXN], n, counter;

    BinaryHeap() : n(0), counter(0) {}
    BinaryHeap(int array[], int offset) : n(0), counter(0) {
        for (int i = 0; i < offset; ++i) {
          heap[++n] = array[i];
          pos[n] = id[n] = n;
        }
        for (int i = n/2; i >= 1; --i) {
          down(i);
        }
    } 

    void push(int v) {
        heap[++n] = v;
        id[n] = ++counter;
        pos[id[n]] = n;
        up(n);
    }

    int pop() {
        swap(heap[1], heap[n]);
        swap(id[1], id[n--]);
        pos[id[1]] = 1;
        down(1);
        return id[n+1];
    }

    int top() {
        return heap[1];
    }

    void up(int i) {
        int x = heap[i], y = id[i];

        for (int j = i/2; j >= 1; j /= 2) {
          if (heap[j] < x) {
            heap[i] = heap[j];
            id[i] = id[j];
            pos[id[i]] = i; 
            i = j;
          }
          else {
            break;
          }
        }

        heap[i] = x;
        id[i] = y;
        pos[y] = i;
    }

    void down(int i) {
        int x = heap[i], y = id[i];

        for (int j = i*2; j <= n; j *= 2) {
          j += j < n && heap[j] < heap[j+1];
          if (heap[j] > x) {
            heap[i] = heap[j];
            id[i] = id[j];
            pos[id[i]] = i;
            i = j;
          }
          else {
            break;
          }
        }

        heap[i] = x;
        id[i] = y;
        pos[y] = i;
    } 

    void erase() {
        n = 0;
    }

    bool isEmpty() {
        return n == 0;
    }
}pq;

int a[MAXN];

int main()
{
    freopen("in.txt", "r", stdin);
    int n;
    cin>>n;
    for (int i = 0; i < n; ++i) cin>>a[i]; 
    pq = BinaryHeap(a, n);
    while (!pq.isEmpty()) {
        cout<<pq.top()<<" ";
        pq.pop();
    }
    return 0;
} 

這道題是裸的最短路。爲了聯繫堆,我們用Dijkstra實現。
手寫堆實現(64ms)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int INF = 0x7fffffff;
const int MAXN = 2000;
const int MAXM = 100000 + 10;

struct Edge{
    int t, w;
    Edge(int a=0, int b=0) : t(a), w(b) {}
    bool operator < (const Edge& x) const{
        return w < x.w;
    }
};

vector<Edge> map[MAXN];

struct BinaryHeap{
    Edge heap[MAXN];
    int n;

    BinaryHeap() : n(0) {}

    void push(Edge v) {
        heap[++n] = v;
        up(n);
    }

    Edge top() {
        return heap[1];
    }

    void pop() {
        swap(heap[1], heap[n--]);
        down(1);
    }

    void up(int i) {
        Edge x = heap[i];

        for (int j = i/2; j >= 1; j /= 2) {
          if (x < heap[j]) {
            heap[i] = heap[j];
            i = j;
          }
          else {
            break;
          }
        }

        heap[i] = x;
    }

    void down(int i) {
        Edge x = heap[i];

        for (int j = i*2; j <= n; j *= 2) {
          j += j < n && heap[j+1] < heap[j];
          if (heap[j] < x) {
            heap[i] = heap[j];
            i = j;
          } else {
            break;
          }
        }

        heap[i] = x;
    }

    bool empty() {
        return n == 0;
    }
}q;

void Dijkstra(int x, int dis[], int n) {
    for (int i = 1; i <= n; ++i) dis[i] = INF;
    dis[x] = 0;
    q = BinaryHeap();
    q.push(Edge(x, 0));
    while (!q.empty()) {
      Edge now = q.top();
      q.pop();
      for (int i = 0; i < map[now.t].size(); ++i) {
        int to = map[now.t][i].t;
        if (dis[to] < dis[now.t] + map[now.t][i].w) continue;
        dis[to] = dis[now.t] + map[now.t][i].w;
        q.push(Edge(to, dis[to]));
      }
    }
}

int a[MAXM], b[MAXM], t[MAXM], dis1[MAXN], dis2[MAXN];

int main()
{
    freopen("in.txt", "r", stdin);
    int n, m, x;
    scanf("%d%d%d", &n, &m, &x);
    for (int i = 1; i <= m; ++i) {
      scanf("%d%d%d", &a[i], &b[i], &t[i]);
      map[a[i]].push_back(Edge(b[i], t[i]));
    }
    Dijkstra(x, dis1, n);
    for (int i = 1; i <= n; ++i) {
      map[i].clear();
    }
    for (int i = 1; i <= m; ++i) {
      map[b[i]].push_back(Edge(a[i], t[i]));
    }
    Dijkstra(x, dis2, n);
    int ans = 0;
    for (int i = 1; i <= n; i++)
      if (i != x)
        ans = max(dis1[i] + dis2[i], ans);
    printf("%d", ans);
    return 0; 
}

priority_queue實現(32ms)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int INF = 0x7fffffff;
const int MAXN = 2000;
const int MAXM = 100000 + 10;

struct Edge{
    int t, w;
    Edge(int a=0, int b=0) : t(a), w(b) {}
    bool operator < (const Edge& x) const{
        return w > x.w;
    }
};

priority_queue<Edge> q;
vector<Edge> map[MAXN];

void Dijkstra(int x, int dis[], int n) {
    for (int i = 1; i <= n; ++i) dis[i] = INF;
    dis[x] = 0;
    q.push(Edge(x, 0));
    while (!q.empty()) {
      Edge now = q.top();
      q.pop();
      for (int i = 0; i < map[now.t].size(); ++i) {
        int to = map[now.t][i].t;
        if (dis[to] < dis[now.t] + map[now.t][i].w) continue;
        dis[to] = dis[now.t] + map[now.t][i].w;
        q.push(Edge(to, dis[to]));
      }
    }
}

int a[MAXM], b[MAXM], t[MAXM], dis1[MAXN], dis2[MAXN];

int main()
{
    freopen("in.txt", "r", stdin);
    int n, m, x;
    scanf("%d%d%d", &n, &m, &x);
    for (int i = 1; i <= m; ++i) {
      scanf("%d%d%d", &a[i], &b[i], &t[i]);
      map[a[i]].push_back(Edge(b[i], t[i]));
    }
    Dijkstra(x, dis1, n);
    for (int i = 1; i <= n; ++i) {
      map[i].clear();
    }
    for (int i = 1; i <= m; ++i) {
      map[b[i]].push_back(Edge(a[i], t[i]));
    }
    Dijkstra(x, dis2, n);
    int ans = 0;
    for (int i = 1; i <= n; i++)
      if (i != x)
        ans = max(dis1[i] + dis2[i], ans);
    printf("%d", ans);
    return 0; 
}

附:堆的基本操作。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN = 100000;
const int INF = 0x7fffffff;

struct BinaryHeap{
    int heap[MAXN], id[MAXN], pos[MAXN], n, counter;

    //將數組中的元素按順序插入所構建的堆 
    BinaryHeap() : n(0), counter(0) {}
    BinaryHeap(int array[], int offset) : n(0), counter(0) {
        for (int i = 0; i < offset; ++i) {
          heap[++n] = array[i];
          pos[i] = id[i] = n;
        }
        for (int i = n/2; i >= 1; --i) {
          down(i);
        }
    }

    void push(int v) {
        heap[++n] = v;
        id[n] = ++counter;
        pos[counter] = n;
        up(n);
    } 

    int top() {
        return heap[1];
    }

    int pop() {
        swap(heap[1], heap[n]);
        swap(id[1], id[n--]);
        pos[id[1]] = 1;
        down(1);
        return id[n+1];
    }

    int get(int i) {
        return heap[pos[i]];
    }

    void change(int i, int value) {
        heap[pos[i]] = value;
        down(pos[i]);
        up(pos[i]);
    }

    void erase(int i) {
        heap[pos[i]] = INF;
        up(pos[i]);
        pop();
        n--;
    }

    void up(int i) {
        int x = heap[i], y = id[i];

        for (int j = i/2; j >= 1; j /= 2) {
          if (heap[j] < x) {
            heap[i] = heap[j];
            id[i] = id[j];
            pos[id[i]] = j;
            i = j;
          } else {
            break;
          }
        }

        heap[i] = x;
        id[i] = y;
        pos[y] = i;
    }

    void down(int i) {
        int x = heap[i], y = id[i];

        for (int j = i*2; j <= n; j *= 2) {
          j += j < n && heap[j+1] > heap[j];
          if (heap[j] > x) {
            heap[i] = heap[j];
            id[i] = id[j];
            pos[id[i]] = i;
            i = j;
          } 
          else {
            break;
          }
        }

        heap[i] = x;
        id[i] = y;
        pos[y] = i;
    }

    bool empty() {
        return n == 0;
    }

    int size() {
        return n;
    }

    void print() {
        for (int i = 1; i <= n; i++) cout<<heap[i]<<" ";
        cout<<endl;
    }
}priorityQueue;

int a[MAXN];

int main()
{
    freopen("in.txt", "r", stdin);
    int n;
    cin>>n;
    for (int i = 0; i < n; i++)
      cin>>a[i];
    //build
    cout<<"Build"<<endl;
    priorityQueue = BinaryHeap(a, n);priorityQueue.print();
    //insert
    cout<<"Insert"<<endl;
    priorityQueue.push(56);priorityQueue.print();
    priorityQueue.push(278);priorityQueue.print();
    //top
    cout<<"top"<<endl;
    cout<<priorityQueue.top()<<endl;;
    //pop
    cout<<"pop"<<endl;
    cout<<priorityQueue.pop()<<endl;
    //get
    cout<<"get"<<endl;
    cout<<priorityQueue.get(2)<<endl;
    //change
    cout<<"change"<<endl;
    priorityQueue.change(2, 3000);priorityQueue.print();
    //erase
    cout<<"erase"<<endl;
    priorityQueue.erase(2);priorityQueue.print();
    return 0;
}
發佈了32 篇原創文章 · 獲贊 1 · 訪問量 3982
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章