1. 程式人生 > >【20171111】 Codevs 1214 線段覆蓋

【20171111】 Codevs 1214 線段覆蓋

delet [0 至少 spa bsp 去掉 logs 給定 範圍

題目描述 Description

給定x軸上的N(0<N<100)條線段,每個線段由它的二個端點a_I和b_I確定,I=1,2,……N.這些坐標都是區間(-999,999)的整數。有些線段之間會相互交疊或覆蓋。請你編寫一個程序,從給出的線段中去掉盡量少的線段,使得剩下的線段兩兩之間沒有內部公共點。所謂的內部公共點是指一個點同時屬於兩條線段且至少在其中一條線段的內部(即除去端點的部分)。

輸入描述 Input Description

輸入第一行是一個整數N。接下來有N行,每行有二個空格隔開的整數,表示一條線段的二個端點的坐標。

輸出描述 Output Description

輸出第一行是一個整數表示最多剩下的線段數。

樣例輸入 Sample Input

3

6 3

1 3

2 5

樣例輸出 Sample Output

2

數據範圍及提示 Data Size & Hint

0<N<100

我想,如果把覆蓋關系轉化為“邊”的話,那麽輸入數據可以轉化為一個圖,

題目就變為:刪掉最少的點,使得圖中剩余點兩兩不能連通。

好簡單呀,就按照每個點的度降序刪點即可!

但是我的代碼速度有待提高……

數組存圖,n^2,

 1 //begin at 16:40
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #define maxn 101
 5 #define _Cover !(ival[i][0]>=ival[j][1]||ival[i][1]<=ival[j][0])
 6 int ival[maxn][3];//interval
 7 //ival[i][2] is the amount of ‘i‘ Coverd intervals
 8 int g[maxn][maxn];//regard the cover
9 int countCover=0; 10 int n; 11 int searchMaxCover() 12 { 13 int ans=0,i,maxi; 14 for(i=0;i<n;i++) 15 { 16 if(ival[i][2]>ans) 17 { 18 maxi=i; 19 ans=ival[i][2]; 20 } 21 } 22 return maxi; 23 } 24 int main() 25 { 26 scanf("%d",&n); 27 int i,j,t; 28 for(i=0;i<n;i++) 29 { 30 scanf("%d%d",&ival[i][0],&ival[i][1]); 31 if(ival[i][0]>ival[i][1]) 32 { 33 t=ival[i][0];ival[i][0]=ival[i][1];ival[i][1]=t; 34 } 35 ival[i][2]=0;//the amount of Coverd intervals 36 for(j=0;j<i;j++) 37 { 38 if(_Cover) 39 { 40 g[i][j]=g[j][i]=1;//create the edges 41 ival[i][2]++; 42 ival[j][2]++; 43 countCover++; 44 } 45 else 46 g[i][j]=g[j][i]=0; 47 } 48 } 49 if(countCover==0) 50 { 51 printf("%d\n",n-1-i); 52 return 0; 53 } 54 int p,q; 55 i=0; 56 while(countCover>0) 57 { 58 i++; 59 p=searchMaxCover(); 60 for(j=0;j<n;j++) 61 { 62 if(g[p][j]==1) 63 { 64 g[p][j]=g[j][p]=0;//delete the edge 65 ival[p][2]--; 66 ival[j][2]--; 67 countCover--; 68 } 69 } 70 if(countCover==0) 71 { 72 printf("%d\n",n-i); 73 return 0; 74 } 75 } 76 return 0; 77 } 78 //end at 17:50

【20171111】 Codevs 1214 線段覆蓋