炫酷路途
https://ac.nowcoder.com/acm/contest/331/D
C++版本一
題解:
std
因為K≤15K≤15,一些人看到這個應該直接就狀壓了,題目放過了這種做法。
但事實上,我們可以將所有額外連邊的點再加上起點終點構成一張單獨的圖。
根據題目數據范圍,上述最多一共只有32個點。
隨后計算這些點兩兩間的距離并求起點到終點最短路即可。(因為是有向圖,非常好求)
P.S : G++編譯環境中,__builtin_popcount(unsigned int)可以$O(1)$計算二進制中該數字1的個數。
時間復雜度O(k2)
#include <bits/stdc++.h> using namespace std;#define pb push_back #define sz(x) (int)x.size()const int mn = 1e3 + 5;int n, k;int a[mn], b[mn]; vector<int> p;inline void addpoint(int x) { p.pb(x); } int dist[mn];int main() {scanf("%d%d", &n, &k);addpoint(1);addpoint(n);for (int i = 1; i <= k; i++) {scanf("%d%d", &a[i], &b[i]);if (a[i] > b[i]) swap(a[i], b[i]);addpoint(a[i]);addpoint(b[i]);}sort(p.begin(), p.end());p.erase(unique(p.begin(), p.end()), p.end());memset(dist, 1, sizeof dist); //賦一個足夠大值dist[0] = 0;for (int i = 0; i < sz(p); i++) {for (int j = i + 1; j < sz(p); j++) {for (int l = 1; l <= k; l++) {//這里寫的過于粗莽,就O(k^3)了if (a[l] == p[i] && b[l] == p[j]) {dist[j] = min(dist[i] + 1, dist[j]);}}dist[j] = min(dist[i] + __builtin_popcount(p[j] - p[i]), dist[j]);}}printf("%d\n", dist[sz(p) - 1]);return 0; }C++版本二
/* *@Author: STZG *@Language: C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int using namespace std; typedef long long ll; //typedef __int128 lll; const int N=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const int INF = 0x3f3f3f3f; int t,n,m,k,q; int ans,cnt,flag,temp; int dp[N]; struct node{int l,r;bool operator <(const node &S)const{return r<S.r;} }e[N]; int dist(int x){return __builtin_popcount(x); } void dfs(int x,int s,int c){//cout<<x<<s<<" "<<c<<endl;if(x==n){ans=min(ans,c);return;}if(ans<=c)return;for(int i=s;i<=cnt;i++){if(x<=e[i].l){int res=c+dist(e[i].l-x);if(e[i].r!=e[i].l)res++;dfs(e[i].r,s+1,res);}} }int main() { #ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout); #endifscanf("%d%d",&n,&m);//scanf("%d",&t);//while(t--){}while(m--){scanf("%d%d",&k,&q);if(k<q){e[++cnt].l=k;e[cnt].r=q;}}e[++cnt].l=n;e[cnt].r=n;ans=INF;sort(e+1,e+cnt+1);dfs(1,1,0);cout << ans << endl;//cout << "Hello world!" << endl;return 0; }?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結