openjudge 高速公路(非prim算法)

来源:互联网 发布:数据库存储多个坐标 编辑:程序博客网 时间:2024/04/30 16:28

这道题是POJ 2485 Highways 的精简版。链接:高速公路


        这道题的标准解法应该是使用prim的最小生成树算法,然后寻找其中的最长边。
        不过我使用了一个非常作死的算法:考虑到路线长度为1~65536之间的整数,我对最长边的长度进行二分查找,对每个最长边的要求生成新图来检测图是否连通。时间复杂度为O(V^2 logW),V为点数,W为路线长度的范围,对这道题来说是500^2*log65536= 4000000。可以在规定时间内跑完。由于判断图连通的算法我只找到O(V^2)的,所以目测过不了POJ2485的原题。或许进行一些优化后可以过吧。
        以下是代码,仅供娱乐~
#include<stdio.h>#include<string.h>bool Mark[520][520];class Highway{public:int from;int to;Highway * next;Highway * last;Highway(){next = this;last = this;}Highway(int from_, int to_, Highway * next_, Highway * last_){from = from_;to = to_;next = next_;last = last_;}};class List{public:Highway * head;List(){head = new Highway;}bool ifempty(){return (head -> next==head);}void instert(int from, int to){Highway * temp = new Highway(from, to, head->next, head);head -> next -> last = temp;head -> next = temp;}void mark (bool B){Highway * temp = head;while(temp -> next != head){temp = temp -> next;Mark[temp -> from][temp -> to] = B;}}};List Ls[66000];int main (){int n;scanf("%d", &n);for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){int t;scanf("%d",&t);Ls[t].instert(i,j);}}int left = 0, right = 65536;int mid = (left + right) / 2;memset(Mark, 0, sizeof(Mark));for (int i = left + 1; i <= mid; i++)Ls[i].mark(1);while(right != left + 1){bool ifr[520];int queue[520], l = 0, r = 1;queue[0] = 0;memset(ifr, 0, sizeof(ifr));ifr[0] = 1;while(r != l){for (int i = 0; i < n; i++){if (Mark[queue[l]][i] && !ifr[i]){ifr[i] = 1;queue[r] = i;r++;}}l++;}if (r == n){right = mid;mid = (left + right) / 2;for (int i =  mid + 1; i <= right; i++)Ls[i].mark(0);}else{left = mid;mid = (left + right) / 2;for (int i =  left + 1; i <= mid; i++)Ls[i].mark(1);}}printf("%d\n",right);return 0;}


0 0
原创粉丝点击