标签:poj
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 4236 | Accepted: 1276 |
Description
Input
Output
Sample Input
5 2 1 3 4 5
Sample Output
3
Hint
题意是给你1到N这么多的点,要求有P次连接,将P次连接中给的点连接起来,举例比如说1到3要连接有两种连接方法,1-2-3或者1-5-4-3。求满足所有连接中最少需要多少个线段连接。
真没想到暴力竟然还能n*n这么暴。。。看了别人的想法之后,觉得精彩的地方第一点在于如果i 到i+1这个线段是断了的话,而要求连接的线段又恰好在这之间,(即只有一种方法将之连接,逆过去连接),这种时候的做法是将to[1]=start,to[end]=N+1,分成两段来想,还避免了那个断了的影响,觉得这种想法真是赞啊!!!
还有一点是to数组的使用比我之前想象的简单多了,to[i]表示从i开始到to[i]已经连接上了,如果等于0直接pass掉,这样一个一个枚举也很简单方便。
还有一点是duandian表示当前能够到达的最远的点,这里的使用也很赞。
这三点真的值得我去好好研磨。
代码:
#include <iostream> #include <vector> #include <algorithm> #include <cmath> #include <string> #include <cstring> using namespace std; struct node { int start; int end; }node_one[10005]; bool cmp(node node1,node node2) { if(node1.start == node2.start) return node1.end< node2.end; return node1.start<node2.start; } #define INF 0x3f3f3f3f int N,P,i,j,Q1,Q2,Qmin,Qmax,ans,h; int to[1005]; int main() { cin>>N>>P; for(i=1;i<=P;i++) { cin>>Q1>>Q2; node_one[i].start = min(Q1,Q2); node_one[i].end = max(Q1,Q2); } sort(node_one+1,node_one+P+1,cmp); ans=INF; for(i=1;i<=N;i++) { memset(to,0,sizeof(to)); for(j=1;j<=P;j++) { if(node_one[j].end>=i+1 && node_one[j].start<=i) { to[1]=max(to[1],node_one[j].start); to[node_one[j].end]=N+1; } else { to[node_one[j].start]=max(to[node_one[j].start],node_one[j].end); } } int duandian=0,result=0; for(j=1;j<=N;j++) { if(to[j]==0)continue; if(to[j]>duandian) { if(j>=duandian) { result+=(to[j]-j); } else { result+=(to[j]-duandian); } duandian=to[j]; } } ans=min(ans,result); } cout<<ans<<endl; return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:poj
原文地址:http://blog.csdn.net/u010885899/article/details/46981157