ÌâÄ¿´óÒ⣺¸ø³öÒ»¸ö·ÑÓÃÁ÷µÄÄ£ÐͺÍÒѾÁ÷¹ýµÄһЩ±ß£¬ÎÊÊÇ·ñ´æÔÚ±ÈÕâ¸ö½â¸üÓŵĽ⡣
˼·£ºÖ±½ÓÓÃÔͼ×öÒ»´Î·ÑÓÃÁ÷Çó×îÓŽâ»áTµô¡£ÏȽéÉÜ·ÑÓÃÁ÷ÏûȦ¶¨Àí£ºÈç¹ûµ±Ç°·ÑÓÃÁ÷µÄ²ÐÁ¿ÍøÂçÖдæÔÚ¸ºÈ¦£¬ÄÇôµ±Ç°Á÷²»ÊÇ×îÓŵĽ⡣
ÆäʵºÜºÃÀí½â£¬½áºÏÔͼºÍÁ÷¹ýÁ÷Á¿Ö®ºóµÄ·´±ß£¬Èô³öÏÖÁ˸ºÈ¦£¬ÄÇô¾Í¿ÉÒÔÑØ×ÅÕâ¸ö¸ºÈ¦Ôö¹ã£¬¶øÇÒ·ÑÓøüС¡£
²»¹ýΪÁ˽â¾öÕâ¸öÌâÎÒÃDz¢²»ÐèÒª½¨Á¢ÍêÕûµÄÍøÂçÁ÷£¬Ö»ÐèÒª½¨Á¢²ÐÁ¿ÍøÂçÖ®ºóSPFA¿´ÊÇ·ñÄÜÕÒµ½¸º»·¼´¿É¡£
¾ßÌ彨Á¢·½·¨£º
Èç¹ûÒ»¸ö±ÜÄѵصãÓÐÖµ£¬ÄÇôTÏòÕâ¸ö±ÜÄѵصãÁ¬±ß£¬·ÑÓÃ0
Èôµ±Ç°±ÜÄѵصãûÓÐÂú£¬ÄÇôÏòTÁ¬±ß£¬·ÑÓÃ0
ÈôÒ»¸öλÖõ½Ò»¸ö±ÜÄѵصãÓÐÔÁ÷Á¿£¬ÄÇôΪÁËÄÜÈÃËûÁ÷»ØÈ¥£¬±ÜÄѵصãÏòÄǸöλÖÃÁ¬±ß£¬·ÑÓÃÂü¹þ¶Ù¾àÀë
ËùÓеÄλÖÃÏòËùÓеıÜÄѵصãÁ¬±ß£¬·ÑÓÃÂü¹þ¶Ù¾àÀë
ÕÒȦʲôµÄËæ±ãyyһϾͺÃÁË- -
CODE£º
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#define MAX 210 #define MAXE 100010 #define T (MAX - 1) using namespace std; struct Point{ int x,y; int cnt; void Read() { scanf("%d%d%d",&x,&y,&cnt); } }start[MAX],_end[MAX]; inline int Calc(const Point &p1,const Point &p2) { return abs(p1.x - p2.x) + abs(p1.y - p2.y); } int m,n; int map[MAX][MAX]; int now[MAX]; int head[MAX << 1],total; int _next[MAXE],s[MAXE],aim[MAXE],length[MAXE]; void Add(int x,int y,int z) { _next[++total] = head[x]; s[total] = x; aim[total] = y; length[total] = z; head[x] = total; } int t[MAX]; int f[MAX],from[MAX]; bool v[MAX]; void FindCircle(int x) { puts("SUBOPTIMAL"); memset(v,false,sizeof(v)); int now = x; while(!v[now]) { v[now] = true; now = from[now]; } int src = now; do { if(from[now] <= m && now != T) ++map[from[now]][now - m]; if(from[now] != T && now <= m) --map[now][from[now] - m]; now = from[now]; }while(now != src); for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) printf("%d%c",map[i][j]," \n"[j == n]); } bool SPFA() { static queue
q; memset(f,0x3f,sizeof(f)); f[T] = 0; q.push(T); while(!q.empty()) { int x = q.front(); q.pop(); v[x] = false; for(int i = head[x]; i; i = _next[i]) if(f[aim[i]] > f[x] + length[i]) { f[aim[i]] = f[x] + length[i]; from[aim[i]] = x; if(!v[aim[i]]) { v[aim[i]] = true; q.push(aim[i]); if(++t[aim[i]] > (m + n + 1)) { FindCircle(aim[i]); return true; } } } } return false; } int main() { cin >> m >> n; for(int i = 1; i <= m; ++i) start[i].Read(); for(int i = 1; i <= n; ++i) _end[i].Read(); for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) Add(i,j + m,Calc(start[i],_end[j])); for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) { scanf("%d",&map[i][j]); now[j] += map[i][j]; if(map[i][j]) Add(j + m,i,-Calc(start[i],_end[j])); } for(int i = 1; i <= n; ++i) { if(now[i]) Add(T,i + m,0); if(now[i] < _end[i].cnt) Add(i + m,T,0); } if(!SPFA()) puts("OPTIMAL"); return 0; }