• codeforces 716d 图论加二分


    参考自:http://www.bubuko.com/infodetail-1762450.html

    题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法,

         使图中的边权值都变为正整数的时候,从 S 到 T 的最短路恰好等于 L。

         若没有输出 "NO",否则输出 "YES",同时输出新图中的所有边权值。

    题解:显然将所有边值都设为1若最短路大于L则无解,所有边值设为INF最短路小于L则无解。

       其他情况一定是有解的。可以想象成将所有的边一次加一,如此循环操作,最短路必定会慢慢加一必定能够到达L;

       那么假设总共有x条权值不确定的边,假设先对第一条边操作,将其不断加一,每加一次跑一遍最短路,始终不能到达L则说明经过第一条边的路必定始终大于L,同理对接下来的边也如此操作。当然这样直接写会很复杂,可以用二分来模拟这个过程,具体就是代码中的cek()函数

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <map>
      7 #include <vector>
      8 #include <queue>
      9 using namespace std;
     10 #define EPS 1e-10
     11 typedef long long ll;
     12 const int maxn = 1e4 + 10;
     13 const double INF = 1e9 +1.0;
     14 int n,m,l,s,t,cnt;
     15 int head[1010];
     16 double dis[1010],gra[1010][1010];
     17 vector<pair<int,int> >q;
     18 vector<int>q1;
     19 struct st1{
     20     int to,nxt,u;
     21     double w;
     22 }edge[maxn*2];
     23 void add(int u,int v,double w){
     24     edge[cnt].u = u;
     25     edge[cnt].to = v;
     26     edge[cnt].w = w;
     27     edge[cnt].nxt = head[u];
     28     cnt++;
     29 }
     30 int dijstra()
     31 {
     32     int i,j,pos=1;
     33     double min;
     34     int visit[1010];
     35     memset(visit,0,sizeof(visit));
     36     double inf = 1e15+1.0;
     37     for(i=0;i<n;++i)
     38         dis[i]= gra[s][i];
     39     visit[s]=1;
     40     dis[s]=0;
     41     for(i=0;i<n;i++)
     42     {
     43         min=inf;
     44         for(j=0;j<n;++j)
     45         {
     46             if(!visit[j]&&min>dis[j])
     47             {
     48                 min=dis[j];
     49                 pos=j;
     50             }
     51         }
     52         visit[pos]=1;
     53         for(j=0;j<n;++j)
     54         {
     55             if(!visit[j]&&dis[j]>dis[pos]+gra[pos][j]){
     56             dis[j]=dis[pos]+gra[pos][j];
     57 
     58             }
     59         }
     60     }
     61     //cout<<dis[t]<<endl;
     62     return dis[t];
     63 
     64 }
     65 int cek(ll sum){
     66     for(int i = 0;i < q.size();i++){
     67         int u = q[i].first,v = q[i].second;
     68         gra[u][v] = gra[v][u] = 1 + min(sum,1000000000ll);
     69         int x = q1[i];
     70         edge[x].w = gra[u][v];
     71         edge[x+1].w = gra[u][v];
     72         sum -= gra[u][v] - 1;
     73     }
     74     return dijstra();
     75 }
     76 int main(){
     77   //  freopen("in.txt","r",stdin);
     78     memset(head,-1,sizeof(head));
     79     scanf("%d%d%d%d%d",&n,&m,&l,&s,&t);
     80     int a,b;
     81     double c;
     82     for(int i = 0;i < n;i++)
     83         for(int j = i; j < n;j++){
     84             gra[i][j] = INF;
     85             gra[j][i] = INF;
     86         }
     87     for(int i = 1;i <= m;i++){
     88         scanf("%d%d%lf",&a,&b,&c);
     89         if(c == 0){
     90             q.push_back(make_pair(a,b));
     91             q1.push_back(cnt);
     92         }
     93         else{
     94             gra[a][b] = gra[b][a] = c;
     95         }
     96         add(a,b,c);
     97         add(b,a,c);
     98     }
     99     ll L = 0,r =(ll)q.size()*1e9;
    100     if(cek(L) > l||cek(r) < l){
    101       // cout<<cek(L)<<" "<<cek(r)<<" "<<l<<endl;
    102         cout<<"NO"<<endl;
    103         return 0;
    104     }
    105     while(L <= r){
    106         ll mid = (L + r)/2;
    107         int temp = cek(mid);
    108         if(temp > l) r = mid;
    109         else if(temp < l) L = mid + 1;
    110         else break;
    111     }
    112     cout<<"YES"<<endl;
    113     for(int i = 0;i <= 2*m - 2;i += 2)
    114         printf("%d %d %0.f
    ",edge[i].u,edge[i].to,edge[i].w);
    115     return 0;
    116 }
  • 相关阅读:
    单例设计模式
    网络编程--Socket与ServerSocket
    JDBC连接Oracle数据库
    ObjectInputStream与ObjectOutputStream
    MyBatis的SQL语句映射文件详解(二)----增删改查
    MyBatis的SQL语句映射文件详解
    MyBatis+Spring实现基本CRUD操作
    通俗解释IOC原理
    Git菜鸟
    hibernate连接oracle数据库
  • 原文地址:https://www.cnblogs.com/shimu/p/5886902.html
Copyright © 2020-2023  润新知