【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)
生活随笔
收集整理的這篇文章主要介紹了
【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題干:
解題報告:
? 主要就是在于怎么處理那個前K個點:組成一個團。換句話說,縮成一個點。先直接當成每個點多了k條邊來處理,T了。想想也是啊,要是K=1e5,那就是1e10條邊了。。剛開始嘗試了半天縮點,后來發現其實不用,只需要把這k個點都連到一個新點上,最后再連回去,然后直接Dijkstra就可以了 。只是相當于多了2*k條邊而已。。真是好題,,,
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; const ll INF = 0x3f3f3f3f3f; int n,m,tot; int head[MAX]; bool vis[MAX]; int k; ll X; ll dis[MAX]; struct Edge {int to;ll w;int ne; } e[MAX<<2]; struct Point {int pos;ll c;Point() {}Point(int pos,ll c):pos(pos),c(c) {}bool operator < (const Point b) const {return c > b.c;} }; void add(int u,int v,ll w) {e[++tot].to = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot; } void Dijkstra(int st) {for(int i = 1; i<=n+1; i++) {dis[i] = INF;vis[i] = 0;} // for(int i = 1; i<=k; i++) dis[i] = X;dis[st] = 0;priority_queue<Point> pq;pq.push(Point(st,dis[st]));while(pq.size()) {Point cur = pq.top();pq.pop();if(vis[cur.pos]) continue;vis[cur.pos] = 1;for(int i = head[cur.pos]; i!=-1; i = e[i].ne) {if(dis[e[i].to] > dis[cur.pos] + e[i].w) {dis[e[i].to] = dis[cur.pos] + e[i].w;pq.push(Point(e[i].to,dis[e[i].to]));}}} } int main() {int t;cin>>t;while(t--) {int st;scanf("%d%d%lld%d%d",&n,&k,&X,&m,&st);//inittot=0;for(int i = 1; i<=n+1; i++) head[i] = -1;ll c;for(int i = 1; i<=k; i++) {add(i,n+1,0);add(n+1,i,X);}for(int a,b,i = 1; i<=m; i++) {scanf("%d%d%lld",&a,&b,&c);add(a,b,c);add(b,a,c);}Dijkstra(st);for(int i = 1; i<=n; i++) printf("%lld%c",dis[i],i == n ? '\n' : ' ');}return 0 ; }// if(cur.pos<=k) { // for(int i = 1; i<=k; i++) { // if(vis[i]) continue; // if(dis[cur.pos] + X < dis[i]) { // dis[i] = dis[cur.pos] + X; // pq.push(Point(i,dis[i])); // } // } // }if(e[i].to <= k) {for(int i = head[n+1]; i!=-1; i = e[i].ne) {if(dis[e[i].to] > dis[n+1] + e[i].w+X) {dis[e[i].to] = dis[n+1] + e[i].w+X;pq.push(Point(e[i].to,dis[e[i].to]));}}} // } // if(cur.pos<=k) { // for(int i = head[n+1]; i!=-1; i = e[i].ne) { // if(e[i].to <= k) { // if(dis[e[i].to] > dis[cur.pos] + X) { // dis[e[i].to] = dis[cur.pos] + X; // pq.push(Point(e[i].to,dis[e[i].to])); // } // } // else if(dis[e[i].to] > dis[cur.pos] + e[i].w+X) { // dis[e[i].to] = dis[cur.pos] + e[i].w+X; // pq.push(Point(e[i].to,dis[e[i].to])); // } // } // } // }?
總結
以上是生活随笔為你收集整理的【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【北航】Bella 姐姐发辣条(贪心)
- 下一篇: 山东多地遭遇入汛以来最强降雨:青岛女子家