1. 程式人生 > >Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)

Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)

air ces ring one show nod pty urn 一個

技術分享圖片

題目大意:給定你一個包含n個點m條邊的無向圖,現在最多在圖中保留k條邊,問怎麽刪除多的邊,使得圖中良好的節點數最多,求出保留在圖中的邊的數量和編號。

  良好的節點定義為:刪除某條邊後該點到點1的最短距離不變。

思路:先求出所有點到點1的最短距離,之後再bfs一遍,若遍歷到某一節點時的距離等於該點到點1的最短距離就將該條邊加進去,直到添加到k條邊或者遍歷結束。(雖然過了但是還是覺得有有的情況好像過不了,但是沒想出來...可能數據還有點水..)

  一開始INF值設小了WA了四次。。。 INF值設置1e15即可,因為邊的權值很大所以上限需要很大。

技術分享圖片
  1 #include<iostream>
  2
#include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<queue> 6 #include<map> 7 using namespace std; 8 typedef long long LL; 9 typedef pair<LL,LL> P; 10 const int maxn = 3e5+10; 11 const LL INF = 1e18; 12 vector<int>ans;
13 int n, m, k; 14 struct node{ 15 LL to,cost; 16 node() {} 17 node(LL a, LL b) :to(a), cost(b) {} 18 }; 19 vector<node> e[maxn]; 20 LL vis[maxn], f[maxn], dis[maxn]; 21 map<P,LL>mp; 22 void SPFA(int s) 23 { 24 for (int i = 0; i < maxn; i++) { 25
vis[i] = 0; f[i] = 0; 26 dis[i] = INF; 27 } 28 dis[s] = 0; 29 vis[s] = 1; f[s]++; 30 queue<int>Q; 31 Q.push(s); 32 while (!Q.empty()) { 33 int t = Q.front(); Q.pop(); 34 vis[t] = 0; 35 for (int i = 0; i < e[t].size(); i++) { 36 LL tmp = e[t][i].to; 37 if (dis[tmp] > dis[t] + e[t][i].cost) { 38 dis[tmp] = dis[t] + e[t][i].cost; 39 if (!vis[tmp]) { 40 vis[tmp] = 1; 41 Q.push(tmp); 42 if (++f[tmp] > n)return; 43 } 44 } 45 } 46 } 47 return; 48 } 49 void BFS(LL x) 50 { 51 ans.clear(); 52 queue<node>Q; 53 memset(vis,0,sizeof(vis)); 54 Q.push(node(x,0)); 55 vis[x] = 1; 56 while(!Q.empty()&&ans.size()<k){ 57 node dep = Q.front();Q.pop(); 58 for(int i=0;i<e[dep.to].size();i++){ 59 LL to = e[dep.to][i].to; 60 if(ans.size()>n-1&&ans.size()<k){ 61 ans.push_back(mp[make_pair(dep.to,to)]); 62 continue; 63 } 64 if(ans.size()==k)return; 65 if(vis[to])continue; 66 if((dep.cost+e[dep.to][i].cost)>dis[to])continue; 67 ans.push_back(mp[make_pair(dep.to,to)]); 68 vis[to] = 1; 69 Q.push(node(to,dep.cost+e[dep.to][i].cost)); 70 if(ans.size()==k)return; 71 } 72 } 73 } 74 int main() 75 { 76 ios::sync_with_stdio(false); 77 while (cin >> n >> m >> k) { 78 mp.clear(); 79 for(int i=1;i<=n;i++)e[i].clear(); 80 for (LL a, b, c, i = 1; i <= m; i++) { 81 cin >> a >> b >> c; 82 e[a].push_back(node(b, c)); 83 e[b].push_back(node(a, c)); 84 mp[make_pair(a,b)] = i; 85 mp[make_pair(b,a)] = i; 86 // cout<<mp[make_pair(a,b)]<<endl; 87 } 88 if(k==0){ 89 cout<<"0"<<endl; 90 continue; 91 } 92 SPFA(1); 93 BFS(1); 94 cout<<ans.size()<<endl; 95 for(int i=0;i<ans.size()-1;i++) 96 cout<<ans[i]<<" "; 97 cout<<ans[ans.size()-1]<<endl; 98 } 99 return 0; 100 }
View Code

Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)