# BZOJ 1614 USACO 07Jan. 洛谷1948 电话线

二分+特殊姿势的check：二分最小代价P，把边权小于等于P的边设为0，其他的设为1，跑一遍最短路，判断dis[n]是否大于K

 1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6 const int maxn=100010;
7 int n,p,k,tot=0,Maxdis=0,last[maxn],dis[maxn];
8 bool v[maxn];
9 struct edge{int to,pre,dis;}e[maxn];
10 struct que{int pos,dis;};
11 struct rec{int x,y,dis;}a[maxn];
12 struct cmp{
13     bool operator() (const que a,const que b){return a.dis>b.dis;}
14 };
15 priority_queue<que,vector<que>,cmp>q;
16
18     k=0; int f=1; char c=getchar();
19     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
20     while ('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
21     k*=f;
22 }
23 void add(int x,int y,int z){e[++tot].to=y;e[tot].dis=z;e[tot].pre=last[x];last[x]=tot;}
24 void dijkstra(int x){
25     dis[x]=0; v[x]=1; q.push((que){x,0});
26     while (!q.empty()){
27         que t=q.top(); int now=t.pos; q.pop();
28         for (int i=last[now],to;i;i=e[i].pre)
29         if (dis[to=e[i].to]>dis[now]+e[i].dis){
30             dis[to]=dis[now]+e[i].dis;
31             if (!v[to]){
32                 v[to]=1;
33                 q.push((que){to,dis[to]});
34             }
35         }
36         v[now]=0;
37     }
38 }
39 bool check(int x){
40     tot=0;
41     memset(last,0,sizeof(last));
42     memset(v,0,sizeof(v));
43     memset(dis,32,sizeof(dis));
44     for (int i=1;i<=p;i++){
45         int d=(a[i].dis<=x)?0:1;
47     }
48     dijkstra(1);
49     if (dis[n]>k) return 0;
50     else return 1;
51 }
52 int main(){
54     if (p<k) return puts("0"),0;
55     for (int i=1;i<=p;i++){
67 }