日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【POJ - 1486】Sorting Slides(思维建图,二分图求必须边,关建边,图论)

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【POJ - 1486】Sorting Slides(思维建图,二分图求必须边,关建边,图论) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he is not a very tidy person and has put all his transparencies on one big heap. Before giving the talk, he has to sort the slides. Being a kind of minimalist, he wants to do this with the minimum amount of work possible.?

The situation is like this. The slides all have numbers written on them according to their order in the talk. Since the slides lie on each other and are transparent, one cannot see on which slide each number is written.?


Well, one cannot see on which slide a number is written, but one may deduce which numbers are written on which slides. If we label the slides which characters A, B, C, ... as in the figure above, it is obvious that D has number 3, B has number 1, C number 2 and A number 4.?

Your task, should you choose to accept it, is to write a program that automates this process.

Input

The input consists of several heap descriptions. Each heap descriptions starts with a line containing a single integer n, the number of slides in the heap. The following n lines contain four integers xmin, xmax, ymin and ymax, each, the bounding coordinates of the slides. The slides will be labeled as A, B, C, ... in the order of the input.?

This is followed by n lines containing two integers each, the x- and y-coordinates of the n numbers printed on the slides. The first coordinate pair will be for number 1, the next pair for 2, etc. No number will lie on a slide boundary.?

The input is terminated by a heap description starting with n = 0, which should not be processed.?

Output

For each heap description in the input first output its number. Then print a series of all the slides whose numbers can be uniquely determined from the input. Order the pairs by their letter identifier.?

If no matchings can be determined from the input, just print the word none on a line by itself.?

Output a blank line after each test case.?

Sample Input

4 6 22 10 20 4 18 6 16 8 20 2 18 10 24 4 8 9 15 19 17 11 7 21 11 2 0 2 0 2 0 2 0 2 1 1 1 1 0

Sample Output

Heap 1 (A,4) (B,1) (C,2) (D,3)Heap 2 none

題目大意:

給出一些重疊的矩形,按照給出的順序分別編號為A、B、C,對于每個矩形給出左下角和右上角的xy坐標(注意讀入順序)。然后再給出一些點,這些點畫在了某個矩形上,根據給出的順序分別編號為1,2,3,對于每個點給出其xy坐標。矩形是透明的所以一次就可以看到所有的點和所有矩形的外輪廓,問能否確定某個點一定在某個矩形上(每個矩形上都有且只有一個點)。

如果可以確定一對編號,則以成對形式輸出確定對應的紙編號和數字(也就是說不一定輸出n對)。如果一個確定的對應都沒有,則輸出none。

解題報告:

不難看出是個二分圖模型,首先判斷是否可以完全匹配,在此基礎上看能否一一對應。也就是說滿足none的情況有兩種,要么是匹配數都不是n,要么是一個必須邊都沒有。

當然這題這么做復雜度還有有點高,在判斷必須邊的時候是n^2枚舉的然后再跑匈牙利,復雜度就有點高,其實可以換種思考方式,如果他是必須邊,那就只可能是你第一次求出的nxt數組中匹配到的值,所以我們可以建邊的時候不是f[j][i]=1,而是f[i][j]=1,然后求出一組nxt賦值給xM數組,這樣枚舉第二維,直接調用xM[i]就可以求出對應的左側的二分圖中的值(第一維),那么直接操作的邊就是f[xM[i]][i],如果去掉這個邊之后match()變了,那么這一定就是必須邊了,直接輸出 i+'A'-1 , xM[i]就行,因為你是枚舉的第二維,而建邊的時候正好就是第二維是紙張(用ABCD表示的那個而非1234表示的那個)而題目要求正好是優先字母的字典序升序,所以正好可以堆起來了。(相應的代碼是AC代碼2)

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 555 + 5; bool used[MAX]; int nxt[MAX],n,f[MAX][MAX]; bool find(int x) {for(int i = 1; i<=n; i++) {if(used[i] == 0 && f[x][i]) {used[i] = 1;if(nxt[i] == 0|| find(nxt[i])) {nxt[i] = x;return 1;} }}return 0 ; } int match() {memset(nxt,0,sizeof nxt);int res = 0;for(int i = 1; i<=n; i++) {memset(used,0,sizeof used);if(find(i)) res++;}return res; } struct Node {int x1,x2,y1,y2; } nn[MAX]; int x[MAX],y[MAX]; int main() {int iCase = 0;while(~scanf("%d",&n) && n) {memset(f,0,sizeof f);memset(nxt,0,sizeof nxt);if(iCase!=0) puts("");printf("Heap %d\n",++iCase);for(int i = 1; i<=n; i++) {scanf("%d%d%d%d",&nn[i].x1,&nn[i].x2,&nn[i].y1,&nn[i].y2);}for(int i = 1; i<=n; i++) {scanf("%d%d",x+i,y+i);for(int j = 1; j<=n; j++) {if(x[i]>=nn[j].x1&&x[i]<=nn[j].x2&&y[i]>=nn[j].y1&&y[i]<=nn[j].y2) f[j][i] = 1;}}int ans = match(),cnt = 0; if(ans != n) {puts("none");continue; }for(int i = 1; i<=n; i++) {for(int j = 1; j<=n; j++) {if(f[i][j] == 0) continue;f[i][j] = 0;if(match() != n) {if(cnt) printf(" "); printf("(%c,%d)",i+'A'-1,j);cnt++;}f[i][j] = 1;}}if(cnt == 0) puts("none"); else puts("");}return 0 ; }

AC代碼2:鏈接

#include<stdio.h> #include<string.h> #include<iostream> #define ll long long #define inf 0x3f3f3f3f using namespace std; typedef pair<int,int> P; const int MAXN = 30; int uN, vN; int g[MAXN][MAXN], linker[MAXN], tmp[MAXN]; bool used[MAXN]; bool dfs(int u) {for(int v = 0; v < vN; v++)if(g[u][v] && !used[v]){used[v] = 1;if(linker[v] == -1 || dfs(linker[v])){linker[v] = u; return 1;}}return 0; } int hungary() {int res = 0;memset(linker, -1, sizeof(linker));for(int u = 0; u < uN; u++){memset(used, 0, sizeof used);if(dfs(u)) res++;}return res; } struct node{int x1, x2, y1, y2; }p[30]; bool inside(P &u, node &v) {if(u.first > v.x1 && u.first < v.x2 && u.second > v.y1 && u.second < v.y2) return true;return false; } int main() {int Heap = 1;while(scanf("%d", &uN), uN){memset(g, 0, sizeof g);vN = uN;for(int i = 0; i < uN; i++)scanf("%d %d %d %d", &p[i].x1, &p[i].x2, &p[i].y1, &p[i].y2);P t;for(int i = 0; i < uN; i++){scanf("%d %d", &t.first, &t.second);for(int j = 0; j < uN; j++)if(inside(t, p[j]))g[i][j] = 1;}printf("Heap %d\n", Heap++);int ans = hungary();if(ans != vN){puts("none\n");continue;}bool flag = 0;memcpy(tmp, linker, sizeof(tmp));for(int i = 0; i < vN; i++){g[tmp[i]][i] = 0;if(ans != hungary()){printf("(%c,%d) ", 'A' + i, tmp[i] + 1);flag = 1;}g[tmp[i]][i] = 1;}if(!flag) puts("none\n");elseputs("\n");}return 0; }

?

總結

以上是生活随笔為你收集整理的【POJ - 1486】Sorting Slides(思维建图,二分图求必须边,关建边,图论)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。