传送门:http://pan.baidu.com/s/1qW6tgS0
T1:
由于题目中要求的东西不好妨碍正常的最短路进行,那么可以枚举它。
也就是二分答案+最短路检测,我写的dijk+heap+读入优化过了
1 #include<queue> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 const int N = 10010; 9 const int M = 50010; 10 #define For(i,n) for(int i=1;i<=n;i++) 11 #define Rep(i,l,r) for(int i=l;i<=r;i++) 12 13 struct EDGE{ 14 int s,t,w; 15 int next; 16 }E[M*2]; 17 18 struct Node{ 19 int node,dis; 20 bool operator <(const Node & A) const{ 21 return A.dis<dis; 22 } 23 }save[N]; 24 bool used[N]; 25 int cost,cnt,n,m,u,v,s,key[N],costs[N],Max; 26 27 void makelist(EDGE A){ 28 A.next = key[A.s];E[++cnt] = A;key[A.s] = cnt; 29 } 30 31 void read(int &v){ 32 char ch=getchar(); 33 int num=0; 34 while(ch<'0'||ch>'9') ch=getchar(); 35 while(ch>='0'&&ch<='9'){ 36 num=num*10+ch-'0'; 37 ch=getchar(); 38 } 39 v=num; 40 } 41 42 void init(){ 43 read(n);read(m);read(u);read(v);read(s); 44 For(i,n) { 45 read(costs[i]); 46 Max=max(costs[i],Max); 47 } 48 For(i,m){ 49 EDGE T; 50 read(T.s);read(T.t);read(T.w); 51 makelist(T); 52 swap(T.s,T.t);makelist(T); 53 } 54 } 55 56 int Dijkstra(int Lim){ 57 priority_queue<Node> q; 58 memset(used,0,sizeof(used)); 59 Node a,b;int tot=0; 60 a.node = u;a.dis = 0; 61 if(costs[u]>Lim) return -1; 62 b.node=b.dis=0; 63 q.push(a); 64 while(!q.empty()){ 65 Node Head = q.top();q.pop(); 66 int p = key[Head.node]; 67 used[Head.node]=true; 68 if(Head.node == v) return 1; 69 while(p){ 70 if(E[p].w+Head.dis<=s&&costs[E[p].t]<=Lim&&!used[E[p].t]){ 71 b.dis = E[p].w+Head.dis; 72 b.node = E[p].t; 73 q.push(b); 74 }p=E[p].next; 75 } 76 while(!q.empty()&&used[q.top().node]) q.pop(); 77 } 78 return -1; 79 } 80 81 bool Check(int Lim){ 82 if(Dijkstra(Lim)==-1) return false; 83 return true; 84 } 85 86 int main(){ 87 init(); 88 int Left=1,Right=Max; 89 while(Right-Left>1){ 90 int Mid=(Left+Right)>>1; 91 if(Check(Mid)) Right=Mid; 92 else Left=Mid; 93 } 94 int ans; 95 if(Check(Right)) ans=Right;else 96 if(Check(Left)) ans=Left; 97 else ans=-1; 98 cout<<ans<<endl; 99 return 0; 100 }
T2:
大水题,相当于几个小水题组合到一起。
前两个问深搜路径即可
最后一问:
不难发现对于任意位置i,它如果可以构成某个常数,
那么加数必然由两部分组成,左边来的和右边来的(记为L_i,R_i)
而显然,Ri=Li+1,Ri+1=SUM-Li+1-A[i+1]。这说明什么?
只要枚举某一项的Li,Ri,便可就出sum,依次往下推。效率:O(lim_LI*Lim_Ri*n)=O(40000*n)
1 #include<queue> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 const int N = 70; 9 const int M = N*N; 10 #define For(i,n) for(int i=1;i<=n;i++) 11 #define Rep(i,l,r) for(int i=l;i<=r;i++) 12 13 struct edge{ 14 int s,t,w,next; 15 }E[M]; 16 17 struct way{ 18 int A[N]; 19 }id,q[N][N*N]; 20 21 int n,m,t,head[N],Es,ans1,cnt[N],ans2,cost[N]; 22 bool vis[N]; 23 void makelist(int s,int t,int w){ 24 E[Es].s=s;E[Es].t=t;E[Es].w=w; 25 E[Es].next=head[s];head[s]=Es++; 26 } 27 28 void DFS(int s,int k,int w){ 29 if(k>n) return; 30 if(k>ans1) ans1=k; 31 if(k%2==0){ 32 if(k>=ans2){ 33 ans2=k; 34 q[ans2][++cnt[ans2]]=id; 35 } 36 } 37 for(int p=head[s];p!=-1;p=E[p].next){ 38 if(!vis[E[p].t]&&w+E[p].w<=t){ 39 vis[E[p].t]=true; 40 id.A[k+1]=cost[E[p].t]; 41 DFS(E[p].t,k+1,w+E[p].w); 42 vis[E[p].t]=false; 43 } 44 } 45 } 46 47 bool cmp(way A,way B){ 48 int p=1; 49 while(p<=ans2){ 50 if(A.A[p]<B.A[p]) return true; 51 if(A.A[p]>B.A[p]) return false; 52 p++; 53 } 54 return false; 55 } 56 57 void Deal(){ 58 Rep(l1,0,200) 59 Rep(r1,0,200){ 60 int sum=id.A[1]+l1+r1; 61 int left=l1,right=r1; 62 bool flag=true; 63 Rep(i,2,ans2){ 64 left=right; 65 right=sum-id.A[i]-left; 66 if(right<0){ 67 flag=false; 68 break; 69 } 70 } 71 if(right!=l1) continue; 72 if(!flag) continue; 73 puts("Yes"); 74 return; 75 } 76 puts("NO"); 77 } 78 79 int main(){ 80 freopen("zroad.in","r",stdin); 81 freopen("zroad.out","w",stdout); 82 memset(head,-1,sizeof(head)); 83 scanf("%d%d%d",&n,&m,&t); 84 vis[1]=true; 85 For(i,n) scanf("%d",&cost[i]); 86 For(i,m){ 87 int x,y,z; 88 scanf("%d%d%d",&x,&y,&z); 89 makelist(x,y,z); 90 }id.A[1]=cost[1]; 91 DFS(1,1,0); 92 cout<<ans1<<endl; 93 sort(q[ans2]+1,q[ans2]+cnt[ans2]+1,cmp); 94 id=q[ans2][1]; 95 For(i,ans2) cout<<q[ans2][1].A[i]<<' ';cout<<endl; 96 Deal(); 97 return 0; 98 }