深度學習 影象分割 分水嶺演算法
阿新 • • 發佈:2021-10-06
給定一個由nn個點和mm條邊組成的無向連通加權圖。
設點11到點ii的最短路徑長度為didi。
現在,你需要刪掉圖中的一些邊,使得圖中最多保留kk條邊。
如果在刪邊操作全部完成後,點11到點ii的最短路徑長度仍為didi,則稱點ii是一個優秀點。
你的目標是通過合理進行刪邊操作,使得優秀點的數量儘可能大。
輸入格式
第一行包含三個整數n,m,kn,m,k。
接下來mm行,每行包含三個整數x,y,wx,y,w,表示點xx和點yy之間存在一條長度為ww的邊。
保證給定無向連通圖無重邊和自環。
輸出格式
第一行包含一個整數ee,表示保留的邊的數量(0≤e≤k)(0≤e≤k)。
第二行包含ee個不同的1∼m 1∼m之間的整數,表示所保留的邊的編號。
按輸入順序,所有邊的編號從11到mm。
你提供的方案,應使得優秀點的數量儘可能大。
如果答案不唯一,則輸出任意滿足條件的合理方案均可。
資料範圍
對於前五個測試點,2≤n≤15,1≤m≤152≤n≤15,1≤m≤15。
對於全部測試點,2≤n≤105,1≤m≤105,n−1≤m,0≤k≤m,1≤x,y≤n,x≠y,1≤w≤1092≤n≤105,1≤m≤105,n−1≤m,0≤k≤m,1≤x,y≤n,x≠y,1≤w≤109。
輸入樣例1:
3 3 2
1 2 1
3 2 1
1 3 3
輸出樣例1:
2
1 2
輸入樣例2:
4 5 2 4 1 8 2 4 1 2 1 3 3 4 9 3 1 5
輸出樣例2:
2
3 2
#include <bits/stdc++.h> #define x first #define y second using namespace std; typedef long long LL; typedef pair<LL, int> PII; const int N =100010,M=200010; int n,m,k; int h[N], e[M], ne[M],w[M],id[M],idx; LL dist[N]; bool st[N]; vector<int> ans; void add(int a, int b, int c,intd) // 新增一條邊a->b,邊權為c { e[idx] = b, w[idx] = c, ne[idx] = h[a], id[idx]=d, h[a] = idx ++ ; } void dijkstra() // 求1號點到n號點的最短路距離 { memset(dist, 0x3f, sizeof dist); dist[1] = 0; priority_queue<PII, vector<PII>, greater<PII>> heap; heap.push({0, 1}); while (heap.size()) { auto t = heap.top(); heap.pop(); int ver = t.second, distance = t.first; if (st[ver]) continue; st[ver] = true; for (int i = h[ver]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > dist[ver] + w[i]) { dist[j] = dist[ver] + w[i]; heap.push({dist[j], j}); } } } } void dfs(int u){ st[u]=true; for(int i=h[u];~i;i=ne[i]) { int j=e[i]; // cout<<j<< ' '; // cout<<st[j]<<' '; if(!st[j] && dist[j]==dist[u]+w[i]) { // cout<<j<<' '; if(ans.size()<k)ans.push_back(id[i]); // cout<<id[i]<<' '; dfs(j); } } } int main() { scanf("%d%d%d", &n, &m, &k); // memset(st, 0, sizeof st); // cout<<st[2]; memset(h, -1, sizeof h); // cout<<st[2]; for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d", &a,&b,&c); add(a,b,c,i); add(b,a,c,i); // cout<<a<<' '<<b<<' '<<c; } cout<<st[2]; dijkstra(); // cout<<st[2]; memset(st, 0, sizeof st); dfs(1); printf("%d\n",ans.size()); for(auto x:ans)printf("%d ",x); return 0; }